All Blog Entries

  1. Funny API function inside ntdll.dll

    Sup ?

    Just while i was bored i and digged a bit inside windows ntdll.dll on winxp sp2.

    the two api functions i found have very funny name declaration:

    Code:
    __stdcall LdrpCheckForSecuROMImage(x)
    __stdcall LdrpCheckForSafeDiscImage(x)
    Im not 100% sure but it seems to be that microsoft is fixing some stuff with special safedisc and securom images. funny, isn't it ?


    This api function is also interesting:

    Code:
    __stdcall LdrpCheckNxIncompatibleDllSection(x)
    Inside it it is checked whether the image is probably a Starfoce or Aspack image.

    It also seems to me that only a russian guy was talking about thoses API functions.
    I hope i can provide more information about it soon.

    Bye

    OH‹en

    Updated February 25th, 2008 at 09:06 by OHPen

    Categories
    Winternals
  2. stuffz

    DDD - Deadline Driven Development :P

    Deadline approaching again, i'm supposed to deliver that great integration-synchronization-soap-service on monday, 56hrs of 60hr estimate used, 6 operations of 15 implemented.

    And then theres the problem of converting shit ("(C00-D48, E14.5-7)*; E23**; E25**; E27**; E89.3**; E89.6**; T86; Z94" stored in a varchar2 column) to gold (
    Code:
    	snip.....
    )... talk about data quality to these guys..

    going to be a long weekend

    Updated April 14th, 2008 at 15:30 by upb

    Categories
    Uncategorized
  3. Виртуелно, виртуелно и машински

    VirtualMachines are really boring, the real art of unpacking is changed with pointless vm reversing. It's really pointless as same result are achived with appending vm, but some authors really crack me up:

    Code:
    (88) mov vm_reg298, 11B0A5B4h
    (39) add vm_reg298, 00000060h
    (97) mov vm_reg298, [vm_reg298]
    (DB) mov vm_reg244, 01101640
    (64) add vm_reg244, vm_reg298
    (6C) mov vm_regDC, 01107414h
    (64) add vm_regDC, vm_reg298
    (97) mov vm_regDC, [vm_regDC]
    (85) mov vm_reg1A4, vm_reg1C
    (26) add vm_reg244, 000000C4h
    (97) mov vm_reg2FC, [vm_reg244]
    (C3) add vm_reg2FC, vm_regDC
    (25) add vm_reg1A4, vm_reg2FC
    (38) sub vm_reg244, 000000C4h
    (DE) mov vm_reg1A4, [vm_reg1A4]
    (A9) mov vm_reg80, vm_reg1C
    (F4) add vm_reg244, 000000C8h
    (D0) mov vm_reg2FC, [vm_reg244]
    (C3) add vm_reg2FC, vm_regDC
    (37) add vm_reg80, vm_reg2FC
    (B3) sub vm_reg244, 000000C8h
    (19) mov vm_reg80, [vm_reg80]
    (98) mov vm_regAC, vm_reg1C
    (5E) add vm_reg244, 000000CCh
    (56) mov vm_reg2FC, vm_reg244
    (C3) add vm_reg2FC, vm_regDC
    (C3) add vm_regAC, vm_reg2FC
    (72) sub vm_reg244, 000000CCh
    (19) mov vm_regAC, [vm_regAC]
    (66) mov vm_reg1F4, vm_reg1C
    (4E) add vm_reg244, 000000D0h
    (97) mov vm_reg2FC, [vm_reg244]
    (64) add vm_reg2FC, vm_regDC
    (C3) add vm_reg1F4, vm_reg2FC
    (B3) sub vm_reg244, 000000D0h
    (A6) mov vm_reg1F4, [vm_reg1F4]
    (85) mov vm_reg2F4, vm_reg1C
    (4E) add vm_reg244, 000000D4h
    (D6) mov vm_reg2FC, [vm_reg244]
    (37) add vm_reg2FC, vm_regDC
    (64) add vm_reg2F4, vm_reg2FC
    (52) sub vm_reg244, 000000D4
    (A6) mov vm_reg2F4, [vm_reg2F4]
    (66) mov vm_regF4, vm_reg1C
    (26) add vm_reg244, 000000D8h
    (97) mov vm_reg2FC, [vm_reg244]
    (64) add vm_reg2FC, vm_regDC
    (93) push vm_reg8
    
    (43) mov vm_reg10, 00000000h                            <---- silent update in vm_context
    
    (0B) add vm_reg3F4, AD3AC892h                           <---- wrongly decoded instruction, due to "silent" update
    This disassembly doesn't give too much hint when doing it staticaly, but when performing it in the live process it makes much more sense. Well especially part where magic filed in vm_context is silently updated... funny... with static tracing this can be located easily as you will get bunch of wrong disasm(last instruction in static tracing), but with properly decoded vm (eg. emulated in live process where we have access to whole progy memory) this lille trick wouldn't even be noticed + we could simply put (in case of emulation) our code instead of making file 40mb larger. Does this count as an owning? Or we have to restore x86 opcodes back... let me know

    for comparing reasons, vm emulator 38kb, all stuff dumped ~20mb... in both cases protection is defeated, but... we make user friendly dump with extra 38kb of code, neet isn't it

    anyway I'm off to play some poker... that thingie is addictive


    aaaaaand game goes on:

    Code:
    (24) mov vm_reg3C8, 0424448Bh
    (11) mov vm_reg3CC, 08244C8Bh
    (24) mov vm_reg3D0, 0004C969h
    (DB) mov vm_reg3D4, 30800000
    (DA) mov vm_reg3D8, FAE240F1
    (AA) mov vm_reg3DC, 505A5958h
    (AA) mov vm_reg3E0, 9090C351h
    (24) mov vm_reg320, F1F17899h
    (24) mov vm_reg324, 85706DF1h
    (DB) mov vm_reg328, F179F5D5
    (6C) mov vm_reg32C, 6C61F1F1h
    (E2) mov vm_reg330, D5957CA9h
    (11) mov vm_reg334, D5ED780Dh
    (9F) mov vm_reg338, 2ED453FEh
    (D8) mov vm_reg33C, 7A0E0E0Eh
    (E2) mov vm_reg340, 957CD5EDh
    (6C) mov vm_reg344, 3270F5D5h
    (DA) mov vm_reg348, F1F1F1A9
    (24) mov vm_reg34C, D5DD70A5h
    (AA) mov vm_reg350, F1F1F1F1h
    (24) mov vm_reg354, F5D5957Ch
    (AA) mov vm_reg358, 70A5F278h
    (E2) mov vm_reg35C, F195D5DDh
    (F9) mov vm_reg360, 957CF1F1h
    (D8) mov vm_reg364, 1D70F5D5h
    (DA) mov vm_reg368, F1F1F1F5
    (AA) mov vm_reg36C, 4AD5ED78h
    (E2) mov vm_reg370, 1220F5E8h
    (E2) mov vm_reg374, 02700D82h
    (DB) mov vm_reg378, 3653F99B
    (43) mov vm_reg37C, AAD5EDD8h
    (E2) mov vm_reg380, 61616132h
    (11) mov vm_reg388, 00000019h
    (66) mov vm_reg38C, vm_reg14
    (1A) add vm_reg38C, 00000320h
    (93) push vm_reg388
    (93) push vm_reg38C
    (98) mov vm_reg38C, vm_reg14
    (9B) add vm_reg38C, 000003C8h
    (8F) call vm_reg38C
    (F9) mov vm_reg388, 4A35B626h
    (87) sub vm_reg2FC, vm_reg58
    (C3) add vm_regF4, vm_reg2FC
    Let's see what is going on when reg38C is executed:

    Code:
    seg000:018C03C8                 mov     eax, [esp+4]
    seg000:018C03CC                 mov     ecx, [esp+8]
    seg000:018C03D0                 imul    ecx, 4
    seg000:018C03D6
    seg000:018C03D6 __more_bre_dekriptujeme:                ; CODE XREF: seg000:018C03DAj
    seg000:018C03D6                 xor     byte ptr [eax], 0F1h
    seg000:018C03D9                 inc     eax
    seg000:018C03DA                 loop    __more_bre_dekriptujeme
    seg000:018C03DC                 pop     eax
    seg000:018C03DD                 pop     ecx
    seg000:018C03DE                 pop     edx
    seg000:018C03DF                 push    eax
    seg000:018C03E0                 push    ecx
    seg000:018C03E1                 retn
    and code which is being decrypted:

    Code:
    seg000:018C0320                 push    89h ; 'Ž'
    seg000:018C0325                 pushf
    seg000:018C0326                 xor     dword ptr [esp+4], 88h
    seg000:018C032E                 nop
    seg000:018C032F                 popf
    seg000:018C0330                 pop     eax
    seg000:018C0331                 lea     esp, [esp-4]
    seg000:018C0335                 mov     [esp], ebx
    seg000:018C0338                 cpuid
    seg000:018C033A                 and     eax, 0FFFFFFDFh
    seg000:018C033F                 mov     ebx, [esp]
    seg000:018C0342                 lea     esp, [esp+4]
    seg000:018C0346                 add     ebx, 58h ; 'X'
    seg000:018C034C                 push    esp
    seg000:018C034D                 sub     dword ptr [esp], 0
    seg000:018C0354                 lea     esp, [esp+4]
    seg000:018C0358                 mov     [ebx], eax
    seg000:018C035A                 push    esp
    seg000:018C035B                 sub     dword ptr [esp], 64h ; 'd'
    seg000:018C0362                 lea     esp, [esp+4]
    seg000:018C0366                 sub     esp, 4
    seg000:018C036C                 mov     [esp], ebx
    seg000:018C036F
    seg000:018C036F loc_18C036F:                            ; CODE XREF: seg000:018C0374j
    seg000:018C036F                 mov     ebx, 0E3D10419h
    seg000:018C0374                 jnb     short near ptr loc_18C036F+3
    seg000:018C0376                 xor     ebx, 0C7A2086Ah
    seg000:018C037C                 sub     [esp], ebx
    seg000:018C037F                 pop     ebx
    seg000:018C0380                 retn
    basicaly this is hiden cpuid check, and value of cpuid is stored to vm_reg58, later on in virtual machine, right after call vm_reg we have this code:

    Code:
    (87) sub vm_reg2FC, vm_reg58
    (C3) add vm_regF4, vm_reg2FC
    vm_reg2FC already has imm+cpuid value, so here we have yet another vm anti-dump...


    some API redirection:

    Code:
    (85) mov vm_regF0, vm_reg1C
    (7A) add vm_regF0, 00000024h      <-- eip offset
    (D0) mov vm_regF0, [vm_regF0]     <-- get ret addy
    (B4) mov vm_regF4, vm_reg1C
    (C4) add vm_regF4, 00000028h
    (F0) mov [vm_regF4], vm_regF0     <-- save ret addy
    (34) single-step check
    (29) mov vm_regF4, vm_reg1C
    (A8) add vm_regF4, 00000024h
    (F9) mov vm_reg90, 10FC5180h
    (19) mov vm_reg90, [vm_reg90]     <-- get api from 10FC5180h
    (FB) mov [vm_regF4], vm_reg90     <-- save it to eip
    (8B) vm_exit                      <-- and we go on...
    API executed from 10FC5180h:

    Code:
    .idata:10FC5180 ; DWORD GetCurrentThreadId(void)
    .idata:10FC5180                 extrn GetCurrentThreadId:dword
    basically when translated to something user friendly = call dword ptr[10FC5180]

    game continues

    Updated October 17th, 2007 at 18:03 by deroko

    Categories
    Uncategorized
  4. Serials and hashing

    In a recent target I encountered a hash function in the serial algorithm. It went something like this:
    Code:
    checksum_hash(string tmp)
      checksum = 0;
      for each char in tmp
        checksum += char;
      checksum = checksum % 9 + 1;
    
      do checksum times
        tmp = string(md5(tmp));
    
      return tmp;
    Apparently just hashing it once wasn't enough The funny thing however was that this hashing provided absolutely no security. It was used like this:
    Code:
    check_if_regged:
      namehash  = checksum_hash(name);
      producthash = checksum_hash("ProductName");
    
      for(i = 0; i < 4; i++)
        key[i] = "ABCDEFGHJKLMNPQRSTUVWXY123456789"[
          (namehash[i] + producthash[i]) % 32
        ];
    
      return checksum_hash(serial1) == checksum_hash(key);
    The last line is true when serial is the same as key. We can calculate key when we know both namehash and producthash, and we know those because we know the product name and the name of the user.

    The hashing adds no security because if we know something we know its hash too. The strength of a cryptographic hash lies in the reverse: if we know the hash, we don't know which input can make that hash. The only good way to use a hash as the main protection is thus to take the hash of something we don't know, like the serial, and compare it to hardcoded hashes.

    P.S. The target had another check on another part of the serial, but it was easily defeated too
    Categories
    Uncategorized
  5. A Framework for Hash Algorithms Analysis

    Hi,

    Before the famous MD5 Weakness discovery, Hash Algorithm security was underevaluated, not many good research attempts were conducted, or better not organised analysis criteria were applied.

    After the MD5-Day, the most important Cryptographys Research Centers (CACR and IACR) moved to more organised Analysis Structures.

    Here I wrote down some Conceptual and Practical assumptions to build a Framework for Hash Analysis

    Analysis is intended to give informations about:

    • General Hashís Architecture
    • Projectual Innovations and/or Old Unsecure Conceptual Adoptions
    • Basical Security Flow Hunting


    There are various different Hash Algorithms, that not necessarily uses all the same techniques, so is Difficult to Establish Efficient Comparing Criteria. The principal attempt of this Conceptual Framework is to move the Attention Point to a superior Abstraction Level, able (or supposed to) to allow the comparison between Different Hash Algorithms.

    So Framework conceptually will divide the Hash Process into:

    • Preprocessing
    • PostProcessing
    • Compression Function
    • Internal Structures (this will be divided in other SubStructures)


    Actually I'm working on a pratical application of this Framework, the hash algorithm used is relatively new (FORK256) and as i could see at the moment, something similar was used to detect a big weakness in this algorithm (paper can be readed on eprint.iacr.org)

    Idea is foundamentally taken from George I. Davida, Jeremy A. Hansen from Center for Cryptography, Computer and Network Security niversity of Wisconsin Works.

    See you to the next post
  6. ВМВаре видимо се : vmware detection

    well I have posted this like 2 months ago, and source of poc is available for a while, but just to write something interesting here we go again.

    Whole story started when TiGa was trying to detect presence of virtual machine using timers, trick was to know if rdtsc is hooked by playing with cr4 and installing own int 0D handler. In fact I answered with a simple poc code to detect all known public implementations of rdtsc faking driver. (I usually don't like to present way of detection, without way to fight it back )

    Code:
                            p586
                            .model  flat, stdcall
                            locals
                            jumps
    
    include                 c:\tasm32\include\shitheap.inc
    include                 c:\tasm32\include\extern.inc
    public C start
    
                            .data
    nothooked               db      "rdtsc not hooked", 0
    hooked                  db      "rdtsc hooked", 0
    
    start:                  push    offset sehhandle
                            push    dword ptr fs:[0]
                            mov     dword ptr fs:[0], esp
    
                            pushf
                            or      dword ptr[esp], 100h
                            popf
                            rdtsc
    __safenop:              nop
                            pop     dword ptr fs:[0]
                            add     esp, 4
                            call    ExitProcess, 0
                            
    sehhandle:              mov     eax, [esp+0ch]
                            cmp     [eax.context_eip], offset __safenop
                            jne     __badbad
                            call    MessageBoxA, 0, o nothooked, 0, 0
                            call    ExitProcess, 0
    __badbad:               call    MessageBoxA, 0, o hooked, 0,0 
                            call    ExitProcess, 0
                            end     start
    Trick consist of setting TF and seeing where exception is generated. All of public implementations, yes, including mine too, had a lille flaw, it didn't tace care of TF when used, all of them used add [esp.reg_Eip], 2 which resulted in int 1 to be generated after instruction after rdtsc if TF is set. This could be used to detect all public implementations of fake rdtsc drivers. When rdtsc is executed we have to check if TF is set in eflags, if so, we have to call int 1 handler (default KiTrap01).

    Oki trick, was good, and I knew we have one way to detect all public fake rdtsc driver. But to be honest I was shocked when Archer author of PhantomOlly and QuickUnpack reported that VmWare even without any kinda of driver got "rdtsc hooked" message. This simply means that vmware didn't take care of privileged instruction which by default is not privileged(rdtsc) and when TF is set. So we got one way to detect 100% sure if vmware is active and in such viri can detect if they are runned in vmware. I highly doubt that malware analysers are using any kinda of fake rdtsc drivers as they don't need them So, my comrades, we have one more way to make viri analysing a lille bit harder in vmware

    wondering if vmware team will fix this flaw in next release till then you may write driver to handle rdtsc properly in vmware

    Updated October 7th, 2007 at 07:39 by deroko

    Categories
    Uncategorized
  7. Свету се немодзе угодити

    Мислим се стварно како људима више не досади да врте ону тему око "поседовања" неке шуљаве заштите. Али што ћете, свету се немодзе угодити. (тастатура ми нема ДЗ слово )

    Но мимо тога, хтедох нешто корисно да постујем, а то је налазење оепа код тхемида (илити дмида). Трик је веома прост и хајде да га показем набрзака. Фора је у процеисрању грешака, наиме дмида поставља свој сех хандлер како би контролисала извршавање ту и тамо грешака које сама себи баца. Међутим, пре него што скочи на оеп она ће вратит назад сех хандлер који је постојао тј. постављен приликом извршавања трида:

    Code:
    [*] Starting target process again
    [*] FS : 0x7FFDF000
    [*] sehhandle ptr : 0x0012FFE0
    малко праћења где дмида поставлља свој сех хандлер:

    Code:
    [*] seh : 0x0012FFE0 EIP return : 0x7C809B67
    [*] seh : 0x0012FFE0 EIP return : 0x00601A0B
    [*] seh : 0x0012FFE0 EIP return : 0x0060A538
    [*] seh : 0x0012FF9C EIP return : 0x0060B2E6
    [*] seh : 0x0012FF9C EIP return : 0x00601A0B
    и на крају пре оепа:

    Code:
    [*] seh : 0x0012FF9C EIP return : 0x00680D7C
    [*] seh : 0x0012FF9C EIP return : 0x00681BD8
    [*] seh : 0x0012FFE0 EIP return : 0x00401000 <----- бинго :)
    [X] Target terminated...
    Кад таргет има вм оеп онда је по мојем истразивању други еип ретурн из вм-а, али све у свему да се лако лоцирати.

    То је то, укратко о брзом налазењу оепа код дмида... горе је био употрбљен оутпут из мог трејсера, али битно је да се види логика

    English ver
    Title: The world can not be pleased

    I'm really impressed that people do not get boread talking about "owning" some average protection, but world can not be pleased.

    Anyway, I planed to show something interesting, this is the trick of locating themida oep very very fast

    Each thread will setup it's own seh in kernel32.dll prior to it's executin (apc -> LdrInitializeThunk -> k32!BaseThreadStart). Oki, while I was writing my tracer for themida I used int 3h to break at the oep, i3here on in sice worked fine and softice would popup, no matter where int 3h occured. On other hand, when I wanted to break with olly using same trick, by simulating exception, themida would simply throw me back MessageBox with some internal exception (yes, themida seh picked up this int3), but this wasn't the case if I simulated exception at the oep. So new idea was born to trace themida till the oep:

    1. log where seh handler is changed
    2. wait when it is restored

    Code:
    [*] Starting target process again
    [*] FS : 0x7FFDF000
    [*] sehhandle ptr : 0x0012FFE0
    seh installed to protected app from exceptions:

    Code:
    [*] seh : 0x0012FFE0 EIP return : 0x7C809B67
    [*] seh : 0x0012FFE0 EIP return : 0x00601A0B
    [*] seh : 0x0012FFE0 EIP return : 0x0060A538
    [*] seh : 0x0012FF9C EIP return : 0x0060B2E6
    [*] seh : 0x0012FF9C EIP return : 0x00601A0B
    and then prior to the oep:

    Code:
    [*] seh : 0x0012FF9C EIP return : 0x00680D7C
    [*] seh : 0x0012FF9C EIP return : 0x00681BD8
    [*] seh : 0x0012FFE0 EIP return : 0x00401000 <----- bingo :)
    [X] Target terminated...
    Of course, all this eip returns are hooked themida vm interpreter as themida will jmp from vm to the oep. It can be vm oep, or normal oep, depending on protection options

    Updated October 5th, 2007 at 19:54 by deroko (added english version at the bottom)

    Categories
    Uncategorized
  8. Some words on how to decrypt trojan Ascesso

    This post is a little bit long, for a better reading you can download the pdf version here: http://www.box.net/shared/static/nexbjpy0p6.pdf

    Roaming around Symantec web pages I stumbled on a review of a trojan named Ascesso. The malware does a lot of things that are described inside the “Technical details” section. I decided to give it a try just because it’s interesting to read what a malware does, but it’s much more funny when you play with it! In this blog entry I won’t talk about what the malware does, but I’ll write something about the way I used to obtain a readable dead list inside Ida. One of the next blog entry could be focused on the analysis of the malware, don’t know.

    The file I’m going to analyze is named asc3550.sys, md5=BBEB49A32417226CABED3E104A9C94B5.
    The malware is crypted, I think it’s a home made protection. If you load the file in Ida you are not able to see too much, almost all the code has been crypted. To view the uncrypted malware you have two options: you can run the driver dumping the memory image using a ring0 dumper (i.e. softice+icedump), or you can use Ida trying to convert the initial output into something really closer to the original driver. Generally, I like to work on a simple dump of the packed/crypted file, but with a driver I prefer to work on a perfect file. With a simple dump of the image you’ll have to deal with instructions like:
    Code:
    .text:0040381B   call  dword ptr ds:0F77B3664h
    .text:004028F9   mov   dword ptr [edi], 0F77AF000h
    .text:0040294E   movzx eax, byte ptr ds:0F77B36D2h
    It’s hard to say what’s going on when you have unknown addresses in front of you. I think you’ll prefer to look at something like:
    Code:
    .text:0040381B   call  ds:_ExAllocatePoolWithTag
    .text:004028F9   mov   dword ptr [edi], offset __ImageBase
    .text:0040294E   movzx eax, ds:byte_4046D2
    This is what I’m going to do.


    Initial decryption
    When you load the file in Ida the decryption routine is the only visible code:
    Code:
    00400240 000    jmp  short loc_400257   ; Entry point
    00400242     sub_400242 proc near
    00400242
    00400242     arg_4= dword ptr  8
    00400242
    00400242 000    lea  edx, [esp+arg_4]
    00400246 000    mov  edx, [edx]
    00400248 000    mov  edx, [edx+0Ch]
    0040024B 000    add  edx, 9540h
    00400251 000    mov  eax, 9AEDh
    00400256 000    retn
    00400256     sub_400242 endp
    00400257     loc_400257:
    00400257 000    call sub_400242
    0040025C 000    pusha
    0040025D 020    push 55Ch
    00400262 024    pop  ecx
    00400263     Decrypt_1:
    00400263 020    mov  eax, [edx]        ; Current dword to decrypt
    00400265 020    sub  eax, 0FA598390h   ; Decryption: sub operation
    0040026A 020    mov  [edx], eax        ; Save the decrypted dword
    0040026C 020    lea  edx, [edx+4]      ; Next dword to decrypt
    0040026F 020    sub  ecx, 4
    00400272 020    test ecx, ecx
    00400274 020    jnz  short Decrypt_1
    00400276 020    popa
    00400277 000    mov  ecx, 9B29h
    0040027C 000    add  edx, 2
    0040027F 000    add  edx, 6
    00400282 000    jmp  edx
    These are the starting instructions. Reading through various forums I had the impression that most of the people have some problems trying to anaylize this kind of snippets. It’s pretty obvious what the snippet does, it’s a simple decryption routine consisting in a sub operation. The main problem is: which part of code will be decrypted? Everything depends on value stored inside edx register, which is obtained by the instructions inside the call 400242:
    Code:
    00400242 lea  edx, [esp+8]     ; stack value
    00400246 mov  edx, [edx]       ; edx is an address !?!
    00400248 mov  edx, [edx+0Ch]   ; edx points to a structure !?!
    0040024B add  edx, 9540h       ; add operation
    How to know the exact value pointed by [esp+8]? Taking in mind that the file I’m analyzing is a .sys file you can get the value inside the stack with a simple deducting reasoning.

    The first driver instruction is the one at 400240, but who brings me there? I mean, there should be an instruction which is executed before the one at 400240. The instruction is a call and it’s somewhere inside IopLoadDriver function (in ntoskrnl.exe):
    Code:
    PAGE:004DCFE2 020 push [ebp+68h+PreviousMode]   ; PUNICODE_STRING RegistryPath
    PAGE:004DCFE5 024 push edi                      ; PDRIVER_OBJECT pDriverObject
    PAGE:004DCFE6 028 call dword ptr [edi+2Ch]      ; Call DriverEntry
    [edi+2C] points to DriverInit, 400240 in this particular case. Look at the last parameter (pDriverObject), it’s really important. You have to concentrate on the stack only, when you are at the first driver instruction you’ll have something like:
    Code:
    esp+00h: IopLoadDriver_return_address
    esp+04h: pDriverObject
    esp+08h: RegistryPath
    esp+0Ch: …
    Here’s how the stack looks like when you are inside the “call sub_400242″, at address 400242:
    Code:
    esp+00h: call_400242_return_address
    esp+04h: IopLoadDriver_return_address
    esp+08h: pDriverObject
    esp+0Ch: RegistryPath
    esp+10h: …
    Now it’s pretty easy to retrieve the starting value of edx:
    Code:
    00400242 lea  edx, [esp+8]        ; edx = pDriverObject
    00400246 mov  edx, [edx]          ; edx points to the first byte of DRIVER_OBJECT structure
    00400248 mov  edx, [edx+0Ch]      ; edx = DRIVER_OBJECT+0Ch
    0040024B add  edx, 9540h          ; edx = edx + 0◊9540
    Just a little more step and you’ll have the value we are searching for. Look a the definition of the DRIVER_OBJECT structure, taken from ntddk.h:
    Code:
    typedef struct _DRIVER_OBJECT {
    CSHORT Type;                   // +0◊00
    CSHORT Size;                   // +0◊02
    PDEVICE_OBJECT DeviceObject;   // +0◊04
    ULONG Flags;                   // +0◊08
    PVOID DriverStart;             // +0◊0C
    ULONG DriverSize;              // +0◊10
    PVOID DriverSection;           // +0◊14
    PDRIVER_EXTENSION DriverExtension;   // +0◊18
    UNICODE_STRING DriverName;           // +0◊1C
    PUNICODE_STRING HardwareDatabase;    // +0◊24
    PFAST_IO_DISPATCH FastIoDispatch;    // +0◊28
    PDRIVER_INITIALIZE DriverInit;       // +0◊2C
    PDRIVER_STARTIO DriverStartIo;       // +0◊30
    PDRIVER_UNLOAD DriverUnload;         // +0◊34
    PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];   // +0◊38
    } DRIVER_OBJECT;
    DRIVER_OBJECT+0Ch is DriverStart, the memory address that points to the first byte of the driver. I don’t have the possibility to know the exact value stored inside DriverStart field, but for a static analysis you can suppose that the address is the ImageBase: 0◊400000. It comes out that the edx value we want is: 0◊400000+0◊9540 = 0◊409540

    It’s time to decrypt the bytes using this simple idc script:
    Code:
    #include 
     static main()
    {
       auto CurrentAddress, i;
       
       CurrentAddress = 0◊409540;
       for(i=0◊55C;i>0;i=i-4)
       {
          PatchDword(CurrentAddress, (Dword(CurrentAddress) - 0xFA598390));
          CurrentAddress = CurrentAddress + 4;
       }
    
       Message(”\nDecryption done, last address: %X”, CurrentAddress);
    }
    I inserted the Message function just because I wanted to see the first non-decrypted address: 0◊409A9C; you can remove the function, if you prefer.
    Ok, now that the decryption is complete I have to look at the decrypted code. The last instruction of the initial decryption routine will bring me directly at a fresh decrypted instruction, which is the next instruction to be executed?
    Code:
    00400276 popa              ; edx = 0◊409540
    00400277 mov  ecx, 9B29h   ; ecx = 0◊9B29
    0040027C add  edx, 2       ; edx = 0◊409540 + 2 = 0◊409542
    0040027F add  edx, 6       ; edx = 0◊409542 + 6 = 0◊409548
    00400282 jmp  edx          ; jmp 0◊409548
    The decrypted code is a small routine, all the other bytes of the file are still crypted; maybe I have to deal with some more layers. The decrypted code contains an initializations part, some calls end a final jmp instruction.


    Initialization

    It’s pretty easy to understand the initialization code. I won’t attach any snippet,it’s only a sequence of mov/add/lea instructions used to retrieve/store some special values that are used later.
    At the end of the initialization part there’s a piece of code which is used to move 0◊44 bytes:
    Code:
    .reloc:00409592 add  edi, [ebp+401BF4h]   ; edi = 400240
    .reloc:00409598 lea  esi, [ebp+401D52h]   ; esi = 409A48
    .reloc:0040959E mov  ecx, 44h
    .reloc:004095A3 rep movsb
    Do you know what 400240 is? It’s the entry point of the file. It’s something to remember for the next decryption script.


    Sections decryption
    The first interesting piece of code is located inside a call at 0◊4095C1, before studying the call I prefer to take a look at the parameters:
    Code:
    .reloc:004095B1 push dword ptr [ebp+401BF8h]   ; ebp+401BF8 and ebp+401BEC were setted
    .reloc:004095B7 push dword ptr [ebp+401BECh]   ; up in the initialization part
    .reloc:004095BD push 1
    .reloc:004095BF push eax
    .reloc:004095C0 push ebx
    .reloc:004095C1 call Decrypt_First_5_Sections
    I can’t get any clue from the parameters, I can’t say nothing else without spying the code. After a little investigation over the previous instructions I discover what the parameters are:
    - ebx = DriverStart
    - eax = 0◊409A38
    - 1
    - dword ptr [ebp+401BECh] = 0◊9540
    - dword ptr [ebp+401BF8h] = 0◊8FA0

    Just wait some minutes and I’ll tell you everything about these parameters.
    As you can see I renamed the call, the name suggests ...

    Updated October 4th, 2007 at 13:09 by ZaiRoN

    Categories
    Uncategorized
  9. Блогујем ја, блогујеш ти....

    Блогујем ја, блогујеш ти, блогујемо сви због изгубљене љубави... блогујем...

    Updated October 3rd, 2007 at 16:41 by deroko

    Categories
    Uncategorized
  10. Something About Firewall Hooking and Packer Filtering #2

    Hi,

    Here the second and last part of my little paper..
    First of all, letís introduce some more specification, to make previous blog entry more clear
    The last struct showed, is the _FIREWALL_CONTEXT_T, and as can be seen there is DIRECTION_E that could be a little obscure, so here is reported:

    Code:
    typedef enum _IP_DIRECTION_E {
      IP_TRANSMIT,
      IP_RECEIVE
    } DIRECTION_E, *PDIRECTION_E;
    Represents easly a packet is Receiver or Transmitted.

    The return values by the filter-routine can be:

    FORWARD = 0
    DROP = 1
    ICMP_ON_DROP = 2


    that are proper of FORWARD_ACTION

    As previously said, to implement IP_SET_FIREWALL_HOOK_INFO, itís necessary to write a filter function for \device\IP, so the pointer (to IP) self can be obtained easly by calling IoGetDeviceObjectPointer( )

    Now can be installed the filter function, by passing througout IPís pointer the address of the filtering function self, with IoBuildDeviceIoControlRequest(IOCTL_IP_SET_FIREWALL_HOOK, IpDeviceObject,Ö..)
    Itís important to say also (according to DDK documentation) that IOCTL_PF_SET_EXTENSION_POINTER registers filter-hook callback to the IP filter driver, to ďmake knownĒ \device\IP to reroute every packet received or transmitted, and finally this same IOCTL clears the filter function from IP device. All these specifications could be made, by filling up the proper structure of this IOCTL, that will go to constitute the InputBuffer of IoBuildDeviceIoControlRequest:

    PF_SET_EXTENSION_HOOK_INFO, that inside have another struct PacketFilterExtensionPtr which specifies the pointer to the filter hook callback, and when ins FALSE clears the filter.

    Code:
    typedef PF_FORWARD_ACTION (*PacketFilterExtensionPtr)(
    
       IN unsigned char *PacketHeader, //Pointer to  Ip header of packet
       IN unsigned char *Packet, //Points a buffer with informations in the packet
    //that filter-hook receives
       IN unsigned int PacketLength , //Length of the packet
       IN unsigned int RecvInterfaceIndex,//Index number for the interface adapter (InGoing)
       IN unsigned int SendInterfaceIndex,//Index number for the interface adapter (OutGoing)
       IN IPAddr RecvLinkNextHop, //IP address for the interface adapter that received the packet
       IN IPAddr SendLinkNextHop //IP address for the interface adapter that will transmit the packet
    );
    See you to the next post
  11. Something About Firewall Hooking and Packet Filtering #1

    Hi,

    This little article is only a more dettailed analysis of an 'old' article from codproject that inspired me.

    Firewall hooking is a task in major part not well documented, MS doesnít provides a clear and exaustive documentation about structures and development, so the only mode to have more knowledge is the RCE method.

    These filter-hooks obviously works only at kernel mode, installing a callback function, and the driver installs a callback into \device\IP (which can be seen with WinObj) but letís also parse \system32\Drivers

    Fortunately, no extreme binary analysis is needed, we can study directly some header file from DDK, and precisely ipfirewall.h, so letís take a deeper look to this file. Immediately we can see two intersing structs, the first is IPPacketFirewallPtr that works as a callout routine, and the most interesting _IP_SET_FIREWALL_HOOK_INFO

    First Struct:

    Code:
    typedef FORWARD_ACTION (*IPPacketFirewallPtr)(
      VOID **pData, //can be pMdl or pRcvBuf
      UINT RecvInterfaceIndex, //Received Data
      UINT *pSendInterfaceIndex, //Index where          data is sent
      UCHAR *pDestinationType, //Can be Local
      Network, Remote, Broadcast, Multicast.
      VOID *pContext, //Points to     _FIREWALL_CONTEXT_T
    UINT ContextLength, //sizeof(FIREWALL_CONTEXT_T)
    struct IPRcvBuf **pRcvBuf
    );
    Second Struct:

    Code:
    _IP_SET_FIREWALL_HOOK_INFO {
      IPPacketFirewallPtr FirewallPtr; // Packet filter   callout.
      UINT Priority; // Priority of the hook
      BOOLEAN Add; // if TRUE then ADD else DELETE
    } IP_SET_FIREWALL_HOOK_INFO, *PIP_SET_FIREWALL_HOOK_INFO;
    This is the heart structure necessary to set-up the filter-hook, which can be done by sending a IOCTL to \device\Ip

    #define IOCTL_IP_SET_FIREWALL_HOOK \
    _IP_CTL_CODE(12, METHOD_BUFFERED, FILE_WRITE_ACCESS)

    IP_SET_FIREWALL_HOOK_INFO will be the Input Structure to be filled for the IOCTL.

    By observing IPPacketFirewallPtr, we can see _FIREWALL_CONTEXT_T which is:

    Code:
    typedef struct _FIREWALL_CONTEXT_T {
      DIRECTION_E Direction;
      void *NTE;
      void *LinkCtxt;
      NDIS_HANDLE LContext1;
      UINT LContext2;
    } FIREWALL_CONTEXT_T, *PFIREWALL_CONTEXT_T;
    After installing the filter-hook, can be powered up a set of rules to FORWARD or DROP a packet.

    Thanks to Jesus O.
  12. Hello World

    Hey There,

    First blog entry here, hope good things will come up

    Wordpress unfortunaly does not have Code Wrappers, here code will have a better look

    Thanks for Blog Feature Woodmann!

    See you to the next post!
    Categories
    TechLife
  13. Making an advanced api redirection more advanced?

    Anyways, I was playing around with a funny target today after school. Its got a bunch of features; I usually break one of them per week This week's "feature to break" was something I have dubbed advanced API redirection.

    Pretty much, what the protection does is take a huge routine of the target program, and stores it in a new section. There it replaces a bunch of the FF 15 calls with its own sort of 'macro', which calls into the protector code, where the protector then does whatever protectors do, and forwards it to the correct api. Here is a good example similar to what I am talking about:

    Original code:
    Code:
    ...
    PUSH 00401000  
    CALL DWORD PTR[11223344] ; VirtualAlloc
    ...
    After protection process:
    Code:
    ...
    PUSHFD
    PUSH EAX
    MOV DWORD PTR[ESP], 1EEDDF40
    XOR DWORD PTR[ESP], 1EADCF40
    POPFD
    PUSH 50010007
    MOV EAX, _protector_routine
    CALL EAX
    ...
    Note:
    the push 50010007 was just a pointer to an identifier used by the protector to see which API to forward to...

    Now this is pretty basic stuff, right? Just search for a byte pattern, execute it, let the code execute up to some hook you have in the code of the protector, where EAX will hold the correct API address, and then just NOP out the entire thing above and replace it with a FF 15 <correct addr>. If you want to be extra neat you could also resolve the XORing obfuscation above to the correct command before obfuscation, which was:
    push 00401000

    Well, the thing is, this protector added a bit o spice to the game. Instead of having just one type of routine that is used for API handling, they used five types. So the above routine could also be:

    Code:
    PUSH 00401000  
    PUSH 50010007
    PUSH EAX
    MOV DWORD PTR[ESP], EDX
    MOV DWORD PTR[ESP], xxxxxxxx
    XOR DWORD PTR[ESP], xxxxxxxx
    POP EAX
    CALL EAX
    and then you have 3 other types of routines that the protector can replace the original call with...

    Now, the trick in the protection is that you have to find and record the byte patterns for all 5 of these routines, and then subsequently fix them back to call dword <correct addr>.

    So, fixing this protection is a two step process:
    1) Identify all of the protector calls
    2) fixing them one by one.

    It is easily automated and fixed, once you have spent an hour hunting down the random crashes in your dump caused because your code has missed one of the protector calls.

    But this got me thinking. What if the protection devs were to add metamorphoses? It shouldn't be hard to write a metamorphic code generator to morph the above 5 routines into even more complex routines.

    Consider: only a couple of the same commands are being used in each of the protector routines:
    CALL EAX...
    MOV DWORD PTR[ESP], xxxxxxx
    XOR DWORD PTR[ESP], xxxxxxx
    ....

    and so on.

    Now, what if for each of those instructions your metamorphic code generator could morph into 4 different code chunks? For example, the CALL EAX could be morphed into:

    Code:
    PUSH EAX
    CALL _geteip
    _geteip:
    POP EAX
    ADD AL, 9
    XCHG DWORD PTR SS:[ESP],EAX
    JMP EAX
    db 0FF
    or

    Code:
    PUSH EAX
    call _geteip
    _geteip:
    POP EAX
    ADD EAX, 0F
    MOV WORD PTR[EAX], 0D0FFh
    MOV EAX, DWORD PTR[ESP]
    ADD ESP, 4
    NOP
    NOP

    and so on...

    Now lets assume that the devs took a couple of hours and coded this simple metamorphic code generator. Now all they have to do is:
    a) protect each call dword ptr with the old method (using one of the 5 possible protector routines)
    b) mark the offsets of each protected CALL in a list for later use
    c) after all the CALL DWORD's have been protected via the old method, take your metamorphic code generator and feed it the list of offsets of protected CALLS, and let it morph each protector routine to a new one.

    After it is done morphing, every single protector routine should be unique. This will throw a wrench in the prospective hacker's plans, because he can no longer easily identify all the protected CALLs that he needs to fix.

    Anyways, this was just an idea I had kicking around in my head for some time. Hope that someone could actually understand it.

    I'll re read this blog post and fix any errors in it later today.

    Updated October 1st, 2007 at 21:04 by rendari (bleh)

    Categories
    Uncategorized
  14. First blog entry ever on Woodmann.com!

    So, the day has finally come, we now have free blogs for all members!

    Sorry for waiting with it until now...

    Any member can from now on have their own, full-featured blog here at woodmann.com, with RSS feed, pingbacks and everything else you would expect from a serious blog host. And of course, the freedom to write about anything you want, as long as you follow our usual rules (i.e. don't post any explicit information about how to remove the protection from any named commercial products, however do note that named malware protection busting for example is completely OK!).

    So, together let's make this the best reversing blog place ever, starting now, and please everyone who already has (or knows someone who has) a reversing blog on some other generic host like Wordpress, Blogger or whatnot, move it here, now!

    Well, don't just stand there, blog away then!


    [EDIT]
    Some useful tips for new bloggers:

    You should normally set the options in your blog control panel to the following (which is also the default suggestion when you view your blog settings):

    Members on buddy list may:
    View Blog
    Leave comments on blog entries

    Everyone else may:
    View Blog
    Leave comments on blog entries

    Our global site settings still makes it so that people who are not members of the board cannot post any comments, so you don't have to worry about any spam, and should not manipulate the settings above to protect against that.

    Similarly, you should not use these global blog settings to hide a non-finished blog post (i.e. a draft) until it is done, since that will also affect all other previous posts on your blog. Instead, simply use "Save draft" button instead of the "Post Now" button when saving it. When you later are later editing the post, and feel that it is ready for the public, simply use the "Publish Status" dropdown in the "Miscellaneous Options" section of the "Additional Options" box that always appears below the main post text field when you are editing/creating a post, and select the "Publish Now" option (instead of the "Draft blog entry" option that will be selected once you have saved a post as a draft) to publish on the blog for everyone to see.

    [EDIT2]
    If you want to subscribe to an RSS feed containing all blog posts in all blogs at woodmann.com, this is the URL of that feed:
    http://www.woodmann.com/forum/blog_external.php

    The feed URLs for individual blogs have the following format, and can be acquired from the "View RSS Feed" link on the page of the blog in question:
    http://www.woodmann.com/forum/blog_external.php?bloguserid=XXXX

    Important note: In order for your blog posts to show up in your RSS feed, you must have your blog permissions set as described above!


    Oh, and while we're talking about RSS feeds, I hope you already know that you can subscribe to such feeds for all posts in the messageboard too, or to the same in any number of selected forums, with the following URLs:

    All posts on entire board:
    http://www.woodmann.com/forum/external.php

    All posts in selected forums:
    http://www.woodmann.com/forum/external.php?forumids=xx,yy,xx,...
    (where the forumids parameter is a comma-separated list with any number of forum ids, which are the id-numbers for each forum that can be seen in the URL field when clicking on the forums in question in the message board index, i.e. the "f" parameter in the URL)

    [EDIT3]
    For some stupid reason the links above don't seem to be visible if you are viewing this post from the blog front-page (they are replaced with "[Link]"). If you want to see the real links, please go to the original blog post by clicking its title at the top of the post.
    Categories
    Uncategorized
Page 11 of 11 FirstFirst ... 4567891011