Archive for the ‘Reversing’ Category

Binary Leetness 300 Comic

Thursday, July 16th, 2009

Okay I’m sure 80% of you would have already seen this comic of ours but I figured I’d publish a link to it from here too…

Mongii, part of the Saphead’s binary analysis team, took the time to create the comic alongside the other Saphead’s and he did a great job may I point out!

Hopefully we’ll be able to produce more work in this form after the Defcon finals :) .

You can find the comic at:
http://hackerschool.org/DefconCTF/17/B300.html

Any feedback is appreciated as always!

Please spread the word where applicable and feel free to leave a pingback if you like. Thank you!

I hope you enjoy the comic as much as I did :) .

“That has got to be the coolest write up, ever, in the history of ever.” – DarkTangent. Glad you like it DarkTangent :) .

It was also nice to see the comic featured on HackADay at http://hackaday.com/2009/07/14/binary-reversing-comic/ :) .

KOrUPt.

Defcon CTF 2009 Potent Pwnable’s 200 write up

Sunday, June 21st, 2009

Okay so ADC was nice to enough to do a write up for the Potent Pwnable’s 200 challenge…

During the qualification round I took a brief look over this challenge and was able to locate the upload scripts and made a note of the SQL commands contained within the files you could download(once they were unpacked)… However I got sidetracked with Binary Analysis so I left this challenge to my team, unfortunately we didn’t solve it… Which makes this write up all the more interesting :) .

As usual you can find it over at Pastie:

http://pastie.org/505249.txt

I’ll have it mirrored locally in a few days.

Nice work Adc! I’m about to read over it now ;) .

KOrUPt.

Defcon CTF 2009 Trivia 400 write up

Wednesday, June 17th, 2009

Seems someone took the time to do a write up for this years Defcon Trivial Pursuits 400 challenge :D .

Let me start by saying me nor my team take any credit for this write up, it’s unclear as to who the author is but my guess is ADC of Loller Skaters produced it? Please correct me if I’m wrong in this assumption.

The write up can be found over at Pastie:

http://pastie.org/510841

I’ve also mirrored it locally just incase, it can be found here:

http://korupt.co.uk/defcon/T400Writeup.txt

I strongly recommend you view the above write up within a web browser(preferably Firefox).

To the author of the above guide, very nice work :) . My team and I didn’t manage to solve the T400 challenge during the qualification round. If you’d like me to update the above links please leave a comment and I’ll do so at the earliest opertunity.

KOrUPt ~ Sapheads.

Haha’s Defcon Crypto Badness 400 write up…

Sunday, June 14th, 2009

Just thought I’d bring this to your attention :)

For those interested in solving the Crypto Badness 400 challenge of the Defcon quals…
Hahah did a very good write up, which can be found at:

http://beist.org/defcon2009/defcon2009_crypto400_solution.txt

Good work Hahah, looking forward to any others you may do :) .

Thanks to T1g3r for bringing the article to my attention :p.

Enjoy!

KOrUPt.

Edit: Author updated.

Defcon CTF 2009 Binary Leetness 300

Thursday, June 11th, 2009

Well, the Defcon CTF 2009 qualifications are over… I’ve decided to do a write up for the Binary Leetness 300 challenge :) .

Feedback appreciated!

Note: your anti-virus may detect the below archive as infected, it contains the b300 binary, which is packed. This is a false positive, I recommend you disable your AV.

http://korupt.co.uk/defcon/B300Writeup.rar

I’ll be posting a more in-depth overview of my experience at the quals shortly.

Enjoy!

KOrUPt ~ Sapheads.org.

Wargaming and idea’s…

Tuesday, February 17th, 2009

Hi all.

First things first, I apoligise for the drought in new posts, I’m very busy at the moment dealing with real life problems and such…

Now on to what I actually wanted to write about.

Recently a friend of mine asked me if I’d like to write a few RE challenges and Wargame services for him… I thought this would be fun and I’ve had a few crafty idea’s :D . The intended platform is a currently undecided Linux distribution. This post documents some of my idea’s and thoughts on the matter :p.

I was thinking about creating some stripped bins and having some fun with RAW sockets, SSL certs, FLIRT signatures, kernel modules and a few other things, if all goes to plan this could be a fun adventure…

Drunken TCP servers and custom encryption schemes come to mind :p.

I was wondering if any of my readers have any idea’s for services I could implement and such?

I’d also like some opinions on how you’d go about throwing together some of the aforementioned things.

As I mentioned earlier, I’m very busy with real lifes issues at the moment so I don’t have much free time. So it could be a while before I actually implement these services.

I’m thinking of setting up an environment similar to the Defcon quals.

If anyone has any feedback or suggestions I’d love to hear them.

If you’d like to lend a hand in implementing a few services don’t hesitate to contact me. Support is something I need at the moment :) .

Hope to hear from you all. Spread the word where applicable.

KOrUPt.

Defcon CTF Catdoord writeup

Monday, January 19th, 2009

Okay so a few days back I got bored and decided to try my hand at some of Defcon’s 2008 CTF binaries.

For those not familiar with Defcon CTF, it’s basically a contest that consists of seven teams of highly skilled individuals. Each team must defend their server and attack the other teams server. For a more in depth description I’ll refer you to this page:

  • http://nopsr.us/ctf2008/overview.html

Now before you go on reading this article… I want to point out that I was unable to get this binary to function correctly(or at all for that matter) on my FreeBsd 6.4 VM… So the write up I’m presenting here is mainly the outcome of my time spent performing static analysis and thus it may be incorrect. I’m hoping that if I am incorrect in my solution that someone may be able to correct me.

Well, of course we start by downloading the binary in question, you can find it here:

  • http://nopsr.us/ctf2008/binaries/catdoord

Thanks go out to 1@stPlace for uploading the binaries :) , If you guys are reading this, I’d really like to hear from you.

We start by checking the file type:

[KOrUPt@Area51 /usr/home/KOrUPt/defcon]$ file catdoord
catdoord: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD),
dynamically linked (uses shared libs), stripped

No debug symbols, this makes disassembling with GDB rather awkward. But it isn’t a problem in this case as I’m using IDA.

I’ll be focusing on explaining the main callback procedure of this binary as the initial routines are near enough the same throughout every other available service. Just to outline the basic functionality:

  1. Listen for connections on port 4341.
  2. Drop “catdoor”’s user privileges.
  3. Accept incoming connections and enter the client callback routine.

The callback routine in question can be found at the following address:

  • 0×080493C0

Upon starting my initial analysis of the callback routine I used HexRays IDA decompiler plugin. This helped simplify a fair amount of the code.

I could see a few uninitialized variable’s being passed to memcpy:

pSzChar = &szChar;
pStruct = &struct[i++]; // 'i' is globally defined
memcpy(pStruct, &szChar, 8u);

the unknown structure is defined as follows:

.bss:0804A7C0 struct          struct_0 200h dup()

Regarding the calls to memcpy(), we see similar code throughout or analysis, this kept me wondering for quite a while but eventually I came to the conclusion that it must be a red-herring of sorts. I’ll go into more detail shortly.

Continuing our analysis we see a few calls to unknown functions, after a little time analysing them, it’s clear that the first seems to be a wrapper for the recv() function.

Its code is as follows and as you can see I’ve named this function “RecvData”:

; int __cdecl RecvData(SOCKET sock, char *buf)
.text:08049338 RecvData        proc near               ; CODE XREF: callback+70
.text:08049338
.text:08049338 fd              = dword ptr -8
.text:08049338 nbytesRecvd     = dword ptr -4
.text:08049338 sock            = dword ptr  8
.text:08049338 buf             = dword ptr  0Ch
.text:08049338
.text:08049338                 push    ebp
.text:08049339                 mov     ebp, esp
.text:0804933B                 sub     esp, 8
.text:0804933E                 mov     [ebp+nbytesRecvd], 0
.text:08049345                 mov     edx, [ebp+fd]
.text:08049348                 lea     edx, [esp+8]    ; first function parameter
.text:0804934C                 mov     eax, edx
.text:0804934E                 mov     [ebp+fd], eax
.text:08049351                 sub     esp, 4
.text:08049354                 push    8               ; size_t
.text:08049356                 push    [ebp+fd]        ; void *
.text:08049359                 mov     eax, ds:i
.text:0804935E                 shl     eax, 3          ; counter << 3
.text:08049361                 add     eax, offset struct
.text:08049366                 push    eax             ; void *
.text:08049367                 inc     ds:i
.text:0804936D                 call    _memcpy
.text:08049372                 add     esp, 10h
.text:08049375
.text:08049375 recvLoop:                               ; CODE XREF: RecvData+5C
.text:08049375                 push    0               ; flags
.text:08049377                 push    4096            ; len
.text:0804937C                 push    [ebp+buf]       ; buf
.text:0804937F                 push    [ebp+sock]      ; s
.text:08049382                 call    _recv
.text:08049387                 add     esp, 10h
.text:0804938A                 mov     [ebp+nbytesRecvd], eax
.text:0804938D                 cmp     [ebp+nbytesRecvd], 4095
.text:08049394                 jg      short recvLoop
.text:08049396                 sub     esp, 4
.text:08049399                 push    8               ; size_t
.text:0804939B                 dec     ds:i
.text:080493A1                 mov     eax, ds:i
.text:080493A6                 shl     eax, 3
.text:080493A9                 add     eax, offset struct
.text:080493AE                 push    eax             ; void *
.text:080493AF                 push    [ebp+fd]        ; void *
.text:080493B2                 call    _memcpy
.text:080493B7                 add     esp, 10h
.text:080493BA                 mov     eax, [ebp+nbytesRecvd]
.text:080493BD                 leave
.text:080493BE                 retn

Again, we see more operations taking place in regard to these mysterious structures. After going over the disassembly it’s worth noting that the data we send to this service does not appear to effect any variable’s used in the operations involving the unknown structure’s. Given we are trying to exploit the service I cannot see how the use of these structures may present a vulnerability and it is for this reason I decided to divert my attention to the other parts of the code.

Whilst writing this a quick thought has come to mind, unfortunately I’m unable to put this theory to the test at the moment, but perhaps an overflow condition is created during the receiving of data over the socket, which in turn overwrites the address of the functions local variable’s and the hardship is that of trying to keep the service up and running? This would address my later concern(which I’ll mention shortly). Any comments?

Disregarding my above sentiments, I shall continue with my explanation.

Just after the call to RecvData(), we’ve a second function being called, this one I’ve decided to call “WriteData”. Its code is as follows:

size_t __cdecl WriteData(int a1, void *buff, size_t length)
{
void *pStruct; // ST00_4@1
char *envHome; // eax@1
FILE *pFile; // eax@1
size_t bytesWritten; // eax@3
size_t pBytesWritten; // [sp+41Ch] [bp-Ch]@1
char filename; // [sp+10h] [bp-418h]@1
FILE *pFile2; // [sp+Ch] [bp-41Ch]@1
void *localStruct; // [sp+8h] [bp-420h]@1
 
pBytesWritten = 0;
memset(&filename, 0, 1024u);
pFile2 = 0;
localStruct = &localStruct;
pStruct = &struct[i++];
memcpy(pStruct, &localStruct, 8u);
envHome = getenv("HOME");
snprintf(&filename, 1024, "%s/.ssh/authorized_keys2", envHome);
pFile = fopen(&filename, "w+");
pFile2 = pFile;
if ( pFile )
{
bytesWritten = fwrite(buff, 1u, length, pFile2);
pBytesWritten = bytesWritten;
if ( (signed int)bytesWritten >= 0 )
fclose(pFile2);
}
--i;
memcpy(localStruct, &struct[i], 8u);
return pBytesWritten;
}

Again we see more operations involving our structures. But more importantly we can see that this code is overwriting the “~/.ssh/authorized_keys2″ file with the data we received over our socket earlier.

In theory, we should be able to generate a pair of DSA keys(public and private), overwrite the authorized_keys2 file with our public key and login via SSH using our chosen passphrase.

To further your understanding of this concept, I’ll quote a web page I read prior to writing this:

DSA key generation
-
While RSA keys are used by version 1 of the ssh protocol, DSA keys are used for protocol level 2, an updated version of the ssh protocol. Any modern version of OpenSSH should be able to use both RSA and DSA keys. Generating DSA keys using OpenSSH’s ssh-keygen can be done similarly to RSA in the following manner:

“% ssh-keygen -t dsa”

Again, we’ll be prompted for a passphrase. Enter a secure one. We’ll also be prompted for a location to save our DSA keys. The default, normally ~/.ssh/id_dsa and ~/.ssh/id_dsa.pub, should be fine. After our one-time DSA key generation is complete, it’s time to install our DSA public key to remote systems.

-

DSA public key install
-
Again, DSA public key installation is almost identical to RSA. For DSA, we’ll want to copy our ~/.ssh/id_dsa.pub file to remotebox, and then append it to the ~/.ssh/authorized_keys2 on remotebox. Note that this file has a different name than the RSA authorized_keys file. Once configured, we should be able to log in to remotebox by typing in our DSA private key passphrase rather than typing in our actual remotebox password.

Once we’ve SSH access there are many things that can be done. As I’m sure you’re aware of. On that note, we have effectively gained a means towards unauthorized access to the target machine(this being a game, we’re not breaking any laws :p).

Now to address my earlier concern… This is too easy! From my past experiences most Defcon services are rather complex, this service just doesn’t seem to be on the same level as the past ones I’ve faced. Thus for some reason I cant help but think I’m wrong in this explanation…

Well, given my current time constraints I’ll wrap this up here.

Please do not hesitate to leave me a comment and as always I hope you liked the read.

I’ll be having a go at some of the other Defcon binaries soon so stay tuned for more writeups :) .

KOrUPt.

Debugging child processes and injectors

Wednesday, January 14th, 2009

A question I get asked quite often is how to go about debugging a child process or a DLL injector. For a Malware analyst knowing these techniques has become a necessity, given most common day Malware uses the aforementioned methods to aid in achieving their goal and sometimes static analysis just isn’t good enough.

For those curios as to what a DLL file is, I shall refer you to the article on Wikipedia:

  • http://en.wikipedia.org/wiki/Dynamic-link_library

I’m sure at least a few readers have come across Malware that has utilized DLL injection in one way or another, but for those who haven’t, I’ll briefly cover some of the various reasons Malware may use these nefarious techniques… Some use the technique in an attempt to bypass firewalls by executing their own code from within a trusted process and others attempt to subvert certain applications that may be used to detect their presence… The list goes on.

Injecting a DLL into a foreign process has become a rather trivial task these days, even more so given the amount of code laying around the internet.

Most commonly you’ll see an injector using the CreateRemoteThread() API, but it’s worth pointing out that there are some less known methods, such as using the undocumented NtQueueApcThread() routine.

In order for a DLL injector to do its work, it has to know whereabouts the target DLL file is located on the system. You can usually find the path to this DLL by setting a breakpoint on the WriteProcessMemory() API, as this API is typically used to write the location of the DLL into the foreign process’s memory.

IDA is mostly used for static analysis and given we’ll be debugging, I’ll be using OllyDbg, of course you can still use your preferred debugger(WinDbg for instance).

Once we have the path of our DLL, we can open it inside our debugger, you’ll typically see the CRT initialization routines, disassembly of a DLL compiled within MSVC6 using optimizations would look similar to this(main routine):

PUSH    EBP
MOV     EBP, ESP
CMP     [ARG.2], 1
JNZ L011
PUSH    0
PUSH    0
PUSH    0
PUSH    DLL.003F105E
PUSH    0
PUSH    0
CALL CreateThread
L011:
MOV     EAX, 1
POP     EBP
RETN    0C

A new thread is created so the process that has been injected with the DLL doesn’t hang. The first comparison is checking the 2nd parameter of DLLMain() is DLL_PROCESS_ATTACH, which is defined as 1.

Upon checking the threads code, we see the following:

PUSH    EBP
MOV     EBP, ESP
SUB     ESP, 0C
PUSH    DLL.003F505C
PUSH    0
CALL FindWindowA
MOV     [LOCAL.1], EAX
MOV     EAX, [LOCAL.1]
PUSH    EAX
CALL GetMenu
MOV     [LOCAL.2], EAX
CALL CreateMenu
MOV     [LOCAL.3], EAX
PUSH    DLL.003F5070
MOV     ECX, [LOCAL.3]
PUSH    ECX
PUSH    10
MOV     EDX, [LOCAL.2]
PUSH    EDX
CALL AppendMenuA
...

Basically, the DLL is obtaining a handle the process’s window and adding a menu, along with subclassing the window procedure(not visible in the above code). The DLL was injected using the traditional CreateRemoteThread() API.

The Just-In-Time debugger comes in handy here, I’ve configured my JIT debugger to be OllyDbg(which can be done via the options menu of OllyDbg), the idea is to cause the injected process to crash, then attach to the process using the JIT debugger.

We can cause the injected process to crash by throwing an exception, we can cause an exception to be thrown simply by overwriting the function prolog/epilog with an INT3(breakpoint) instruction. For those who don’t know what I mean by prolog, I’m referring to the instructions that set up the functions local stack, those being:

PUSH    EBP
MOV     EBP, ESP
SUB     ESP, 0C

We can overwrite the PUSH EBP instruction with an INT3 instruction and restore the overwritten bytes once attached to the process.

Overwrite the instruction, save the changes and run the DLL injector/Sample, once the DLL has been injected, the target process will hopefully crash and the MS Error Reporting dialog will appear, upon clicking clicking the “Debug” button OllyDbg will launch and attach to the process.

If you’re not currently paused at the INT3 instruction press Alt + F9(pass exception) until you reach it. We can then restore the original instruction, that being “PUSH EBP” and step through the code as normal.

I feel the need to point out that the above steps should only be used within a controlled environment, as some Malware sample’s can be crafty…

For instance, a custom SEH(Structured Exception Handler) may be setup to catch exceptions which means the MS Error Reporting dialog will not appear and the process may execute a fall back routine. We can circumvent custom SEH but I’ll be saving that for another article. For those eager, it mainly involves overwriting the current exception handler with the one used within kernel32.

We can use the same technique described above to debug child process’s.

For Linux users, GDB offers a few useful functionalities to follow child process’s, it can be configured to follow fork()’s and such by issuing the following commands:

  • set follow-fork-mode child
  • set detach-on-fork     on

It can be useful to follow a child process sometimes, as most of the time a certain possibly important routine is only carried out inside the child process.

As for debugging sample’s that use DCI(Direct Code Injection), we can again breakpoint the WriteProcessMemory() API and modify the buffer of instructions that is being written into the target process so it contains an INT3 instruction, after which we can proceed as mentioned previously…

And on that note, I think that just about covers this article.

I look forward to reading any questions and or comments you may have. Let me know of any experiences you have have had whilst debugging such Malware sample’s.

I hope you enjoyed the read.

KOrUPt.

Keygening anyone?

Friday, December 26th, 2008

Below is a KeygenMe I’ve created for your enjoyment :P . This is one of my first.

Admittedly I could have made the algorithm considerably harder, but I didn’t want to overkill the first KeygenMe I released, so I kept it simple.

If you manage to Keygen it, consider writing a tutorial on how you did it, please leave a comment and let me know how you’re progressing.

Level: Intermediate.

Protection: Packed with UPX.

Rules: No Self-Keygening, no patching.

I may write a tutorial on how to beat it soon.

Any questions and or suggestions or similar, please leave a comment and I’ll get back to you as soon as possible.

Thanks for your time and happy cracking :) . Have a good new year.

Download: http://korupt.co.uk/KeygenMe1.exe

KOrUPt.

 

 

How the ESP trick actually works

Monday, December 22nd, 2008

Earlier today a friend of mine asked for assistance unpacking a custom built packer/protector… After I’d skimmed the disassembly I could see the ESP trick was a viable option once the anti-debug had been circumvented.

I decided to ask him if he’d heard about the ESP trick, he replied that he had used it quite a few times in the past. When I decided to ask him if he knew how it actually worked he told me that he didn’t know.

I’ve come across a lot of reverse engineers in my time, some experienced, others inexperienced… Roughly 40% of them had heard about and used the ESP trick at one point or another, but none knew how it actually worked.

That said I thought I’d write about the topic, so that next time someone asks me I can link them here.

When we encounter a PUSHAD instruction at a packed files entrypoint, we can usually assume the ESP trick is a viable option.

So what does the PUSHAD instruction do? It simply pushes all registers onto the stack, the main reason for doing this is because some packers like to preserve/restore the initial registers contents once the original entrypoint is reached…

This is done via the POPAD instruction, which pops the registers contents off the stack and back into the registers.

Once we step over a PUSHAD instruction we can see that the ESP register’s contents has updated, the ESP register always points to the top of the stack, hence its name, Extended-Stack-Pointer.

Once we follow this register’s contents in the dump and set a hardware breakpoint(type: on access. size: dword) at its address, we know that once that address is accessed our hardware breakpoint will be triggered.

The POPAD instruction access’s our address and thus triggers our hardware breakpoint, once the registers are restored a packer will usually execute the now uncompressed code(which is why we usually see a JMP/RETN instruction just after a POPAD instruction).

You may be wondering why we need a hardware breakpoint as oppose to a software breakpoint, the problem with software breakpoints is that our debugger places an int3 instruction(0xCC byte) at our target address, this will corrupt our registers contents… Which is not what we want.

I think that just about covers this explanation. I hope you found this post helpful in some way.

As always, if you’ve any questions, post a comment and let me know.

KOrUPt.