📚 OpenRCE is preserved as a read-only archive. Launched at RECon Montreal in 2005. Registration and posting are disabled.








Flag: Tornado! Hurricane!

Blogs >> Dreg's Blog

Created: Saturday, January 16 2010 11:21.08 CST Modified: Saturday, January 16 2010 11:24.50 CST
Direct Link, View / Make / Edit Comments
Rootkit Arsenal, Installing a Call Gate
Author: Dreg # Views: 35768

This is a part of the translation of my spanish post published in blog.48bits.com:

Hi, I was reading the book �The Rootkit Arsenal: Escape and Evasion in the Dark Corners of the System� and I'd like to qualify a few things about the chapter �Hooking the GDT - Installing a Call Gate�. A PoC driver is included at the end of the article that supports WalkGDT for multiple COREs.

A Call Gate is a mechanism in the Intel x86 architecture to change privilege levels of the CPU when running a predefined function that is called by the instruction CALL/JMP FAR.

A call to a Call Gate allows you to obtain higher privileges than the current, for example we can execute a routine in ring0 using a CALL FAR in ring3. A Call Gate is an entry in the GDT (Global Descriptor Table) or LDT (Local Descriptor Table).

Windows doesn't use Call Gate for anything special, but there are malware, as the worm Gurong.A, that installs a Call Gate via DevicePhysicalMemory to execute code on ring0. An article that talks about it is "Playing with Windows/dev/(k)mem" by crazylord and published at Phrack 59.

Nowadays we can't easily access to /Device/PhysicalMemory, I recommend reading the presentation by Alex Ionescu at RECON 2006 "Subverting Windows 2003 SP1 Kernel Integrity Protection". Also, there are examples in the wired that use the API ZwSystemDebugControl to install a Call Gate, but Ionescu's article says that it doesn't work nowadays (although there are techniques to reactivate them).

...
Now is time for a more detailed view, the POC code of the book doesn't allow the possibility of multiple CORES, this means that is only able to install the Call Gate in the CORE assigned when the driver is loaded and the GDT of the oher CORE remains intact, the problem is that if the userspace application makes a FAR CALL being in another CORE where there is no Call Gate, so it doesn't work.
...

You can view the orginal and official Spanish post in:
http://blog.48bits.com/2010/01/08/rootkit-arsenal-installing-a-call-gate/

And the English post in my rootkit.com blog:
http://www.rootkit.com/blog.php?newsid=992

Translated by Laura Garcia from http://www.securitybydefault.com/

Sincerely, Dreg.

Created: Monday, January 11 2010 15:03.25 CST Modified: Monday, January 11 2010 17:20.51 CST
Direct Link, View / Make / Edit Comments
X86IME from x86pfxlab
Author: Dreg # Views: 5452

Hello OpenRCE, Today I will talk about the X86IME engine (OpenSource), this engine is a x86 and x86_64 (32/64bits) disassembler/assembler of my friend Pluf.

The engine:

It exist an intermediata object called x86im_instr_object, with this object you can: generate intructions, view dissasembly like a LDE or like INTEL syntax directly:


typedef struct _x86im_instr_object                      // x86 decoded/generated instruction:
{
    unsigned long mode;                                 // mode: 32/64bits
    unsigned long flags;                                // instr flags
    unsigned long id;                                   // instr id
    unsigned long grp;                                  // instr grp & subgrp
    unsigned long mnm;                                  // instr mnemonic

    unsigned long len;                                  // total instr length

    unsigned char def_opsz;                             // default operand size: 1/2/4/8
    unsigned char def_adsz;                             // default address size: 16bit = 2 | 32bit = 4 | 64bit = 8

    unsigned char opcode[3];                            // instr opcodes: up to 3
    unsigned char opcode_count;                         // instr opcode count

    unsigned short prefix;                              // instr prefixes ( mask )
    unsigned char prefix_values[4];                     // prefixes
    unsigned char prefix_count;                         // instr prefix count
    unsigned long prefix_order;                         // instr prefix order
    unsigned char rexp;                                 // REX prefix
    unsigned char somimp;                               // mandatory prefix: SOMI instr only: 0x66|0xF2|0xF3
    unsigned char n3did;                                // 3dnow instr id
    unsigned char seg;                                  // implicit segment register used by mem operands:

    unsigned char w_bit;                                // wide bit value: 0/1 - if IF_WBIT
    unsigned char s_bit;                                // sign-extend bit value: 0/1 - if IF_SBIT
    unsigned char d_bit;                                // direction bit value: 0/1 - if IF_DBIT
    unsigned char gg_fld;                               // granularity field value: 0-2 ( mmx ) - if IF_GGFLD
    unsigned char tttn_fld;                             // condition test field value: if IF_TTTN

    unsigned short selector;                            // explicit segment selector used by CALL/JMP far: IF_SEL

    unsigned long imm_size;                             // imm size: 0 | (1/2/4/8)
    unsigned long long imm;                             // imm value: 64bit max value ( if imm_size != 0 )

    unsigned long disp_size;                            // disp size: 0 | (1/2/4/8)
    unsigned long long disp;                            // disp value: 64bit max value ( if disp_size != 0 )

    unsigned char mem_flags;                            // mem flags: src/dst/..
    unsigned short mem_am;                              // addressing mode
    unsigned short mem_size;                            // operand size ( xxx ptr )
    unsigned char mem_base;                             // base reg : grp+id
    unsigned char mem_index;                            // index reg: grp+id
    unsigned char mem_scale;                            // scale reg: grp+id

    unsigned char modrm;                                // modrm byte value & fields: if IF_MODRM
    unsigned char sib;                                  // sib byte value & fields: if IF_SIB

    unsigned long rop[4];                               // imp/exp reg op array
    unsigned char rop_count;                            // imp/exp reg op count

    unsigned int status;
    void *data;

} x86im_instr_object;


To dissasembly a instruction you need the parameters: x86im_instr_object, the mode X86IM_IO_MODE_32BIT or 64BIT, the data, is the buffer with the instruction.


int __stdcall x86im_dec( __inout x86im_instr_object *io,
                          __in unsigned long mode,
                          __in unsigned char *data )


Example of dissasembly of POP EAX instruction:


x86im_instr_object io;
char *d = "\x58"; /* POP EAX, OPCODE */
x86im_dec( &io,
            X86IM_IO_MODE_32BIT,
            d );


You can access to INTEL syntax string with io.data

To generate an instruction, you need two steps, first generate a valid instruction with the code and operands reg/mem/disp/imm:


int __stdcall x86im_gen( __inout x86im_instr_object *io,
                          __in unsigned long options,
                          __in unsigned long code,
                          __in unsigned long reg,
                          __in unsigned long mem,
                          __in unsigned long long disp,
                          __in unsigned long long imm )


Example of the generation of a POP EAX instruction:


x86im_instr_object io;
x86im_gen( &io,
            X86IM_IO_MODE_32BIT|X86IM_GEN_OAT_NPO_D,
            X86IM_GEN_CODE_POP_RG1,
            X86IM_IO_ROP_ID_EAX, 0, 0, 0 );


There are many macros very very useful in the headers, like X86IM_GEN_CODE_POP_RG1 or macros like: X86IM_IO_IS_GPI_ADC(x) to check the ( ( (x)->id & 0xFFF0 ) == 0x0060 ), with this macros the code is very intuitive and you do not need hardcode values with many coments... IMHO, of course.

The nex step is the instruction encode with the x86im_enc interface:


int __stdcall x86im_enc( __inout x86im_instr_object *io,
                          __out unsigned char *data )


With this function you get the real instruction in data buffer, to get the raw instruction in data of the POP EAX instruction generated in io with x86im_gen instruction:


x86im_instr_object io;
char data[1];
x86im_enc( &io, data );


Now, you can dump the raw instruction stored data in somewhere.

With this powerful engine you can generate the same instruction with redundancy, for example of the ADD instruction:

Raw instruction: 03 C3
INTEL representation: ADD EAX, EBX
Mod:11, reg:000 and r/m:011

The same representation is with this raw: 01 D8, Mod:11 reg:011 and r/m:000.

You can generate any redundancy using the macros without hard values.

Donwload X86IME v1.0: http://sites.google.com/site/x86pfxlab/projects

The examples of the engine are very useful,

instdec: sample instruction dissasembler.

instgen: sample instruction generator, in the output you can view the code redundancy etc.

Patch to compile in UNIX by nibble: http://nibble.develsec.org/get/x86im-1.0b.tar.gz

CFLAGs for WINDOWS:
CFLAGS+=-D__WINDOWS__=1

CGLAGS in UNIX:
CFLAGS+=-D__UNIX__=1

It exist a unix sample version with makefiles for each win sample.

Sincerely, Dreg.

Created: Wednesday, December 16 2009 14:57.00 CST Modified: Wednesday, December 16 2009 16:09.09 CST
Direct Link, View / Make / Edit Comments
dwtf released!
Author: Dreg # Views: 4807

dwtf creates a fake.dll from real.dll

Features:

1- It exports all symbols of real.dll (also Forwarder).

2- It imports all exports of real.dll (also Forwarder).

3- It creates an area code with a JMP DWORD [ADDRESS] for each export.

4- The exports of fake dll is assigned to a JMP area which jumps to original export of real.dll.

Download: http://rootkitanalytics.com/userland/dwtf.php

For more complex information visit my post in rootkit.com:

Generating any DLL for PEB Hooking or replacing in disk, binary form:
http://www.rootkit.com/blog.php?newsid=988

If you are making PEB HOOKING, when the APP calls to fake dll export it jumps to original export, everything works fine:
Before PEB HOOKING:
APP -> IAT OF APP -> REAL DLL EXPORT

After PEB HOOKING:
APP -> IAT OF APP -> FAKE DLL EXPORT -> IAT OF FAKE DLL -> REAL DLL EXPORT

You can add or remove payloads with any IAT HOOKING in the IAT of the fake dll:
APP -> IAT OF APP -> FAKE DLL EXPORT -> IAT OF FAKE DLL -> PAYLOAD STACK -> (or never) REAL DLL EXPORT

Syntax: dwtf.exe fake_dll real_dll

Example: dwtf.exe k32.dll c:\windows\system32\kernel32.dll

Sincerely, Dreg.

Created: Monday, October 12 2009 19:16.01 CDT Modified: Monday, October 12 2009 19:19.05 CDT
Direct Link, View / Make / Edit Comments
Understanding WinXPSP2.Cermalus coded by Pluf
Author: Dreg # Views: 5251

Hello people, here my explanation of the WinXPSP2.Cermalus malware, this malware have a ring0 component which hook:

   1. NtOpenFile: This routine infects the .exe, except the .exes inside windows directory. It checks if the .exe is already infected.

   2. NtEnumerateBootEntries: It returns STATUS_SUCCESS when the args are: "0xBEBE, 0xCAFE".

   3. NtDebugActiveProcess: It blocks the attach to ring3 process.

   4. DbgPrint/DbgPrintEx/DbgPrintReturnControlC: It blocks the debug using DbgPrint*

   5. PsSetCreateProcessNofityRoutine/PsSet//RemoveCreateThreadNotifyRoutine/: It returns STATUS_SUCCESS, but the hook is empty. It is useful to evade software monitors like ProcMon..

Dropper and ring3 component which load driver and other stuff, full explanation at:

http://biht.blogspot.com/2009/10/understanding-winxpsp2cermalus.html

you can download the src of virus here: http://66.98.184.55/%7Ebihtstor/vx/WinXPSP2.Cermalus/WinXPSP2.Cermalus.asm

Created: Wednesday, August 5 2009 08:43.14 CDT  
Direct Link, View / Make / Edit Comments
One safe hook handler - E8 Method, paper
Author: Dreg # Views: 8731

There exist different libraries to set hooks, lot of them in Windows, but
time ago we faced a specific problem for which no solution nor documentation
were found about. The problem is: how to setup hooks for several APIs in runtime,
reading from a configuration file that gives the APIs and prototypes? When
discussing about this idea I got another question in response: why do you want to
do that? My answer was: I don't want to develop a different handler for every hooked API
and compile every time for it to work, and I don't want to build a run time Handler creator.
We cam sum up in two requisites:

    1.- Use some kind of technology that does not require previous compiling.

    2.- Develop some kind of macro to simplify the coding and reduce compile errors.

As I was not convinced of these solutions, I started to think about this problem
and about what I really want, so the right question appeared: What do I need to
do what I want? And the answer is simple: Having one handler for every hook, just
know when it is called, which API/hook is the caller and then take proper decissions.
That's it!, I need and "API ID". Or best expressed, I need a "hook_caller ID"

This is the point where I need to mention that the hook method I need is "Detours"
[R.9] [R.6], said, insert a JMP, PUSH + RET ... in the address where we want
to place the hook. I selected this method [R.9] taking care about that
some of the other methods have a problem when you call directly the memory address where the
hook lies, so the handler it is not executed, i.e. IAT HOOKING.  In the methods that
insert JMP, PUSH + RET... in reserved memory or padding bytes, direct calls don't
execute the handler. As my first priority was to intercept every call to the hooked APIs,
the "Detours" method [R.9] [R.6] that overwrites instructions where we want our hook
placed, looked the best. Though this method implies the use of some kind of LDE
(Length-Disassembler Engine) [R.7], among other things, there exist libraries in the
web that allow us to use this method in Windows without any trouble.

Now, we just need only  to answer the question: how can I know which hook
is calling the handler in runtime? After some serious thinking about the problem
I got an "Eureka!": I will replace the JMP method by a CALL-style method, and
I will check from the hanlder the return address that CALL places in the stack,
using this return address as the "hook_caller ID". As every hook is in a different
memory position, every CALL will place a different value in the stack, so it can
be used as an identificator. Then, we need only to modify the normal method so
the handler will process this "hook_caller ID" and will remove it from the stack.

Problem solved. Now the last thing left was to find a name, this name appeared
when coding the problem: "E8 Method". As a JMP (no SHORT) in the address
XXXXXXXX to YYYYYYYY, will be coded as: "E9 ZZZZZZZZ", and a CALL from the same
address to the other address will be coded as: "E8 ZZZZZZZZ". Eureka! (again).
The part that changed was the opcode for the instruction, as it was opcode for CALL, E8, so
I decided to call the method "E8 Method". But "E8 Method" it is not only to replace
the JMP type hook by the CALL type, it is the concept and/or the style of implementing
a global handler ("One hook handler") that could obtain the "hook_caller ID" in runtime.


After the development of the first proof of concept (POC) I had some problems, like stack
buffer overflows when the hooked APIs where called directly and indirectly from the hooh
handler, Microsoft Visual Studio checks to detect when the stack is corrupted using the
EDI value my hook handler was modifying internally, etc. So it was not only to create a
hook handler; I have had to create a safe hook handler taking care of most of there problems.

As long as the project grew it was neccesary to code some pieces in C/C++
resulting a problematic hybrid code between ASM/C/C++, so I developed a low-level layer
that allowed me to code everything in C/C++ without further troubles. There appeared some stack
buffer overflows too when calling the hooked API, but I found an ellegant solution in the
easy hook called Threat Deadlock Barrier (TDB) [R.8].

This documento is about how to use and implement the "E8 Method" with only one
hook handler for every hook that will be safe and will be implemented in C/C++: "One safe Hook Handler".

Two public libraries, where a hack has been applied, will be used:

    1.- Microsoft Detours Library [R.6]
    2.- Easy-Hook [R.8]

Download in English:
http://fr33project.org/papers/One%20safe%20hook%20handler%20-%20E8%20Method.txt

Download in Spanish:
http://fr33project.org/spanish/papers/One%20safe%20hook%20handler%20-%20E8%20Method.txt


Archived Entries for Dreg
Subject # Views Created On
CreateRemoteThread into not yet initialized process (CREATE_PROCESS_SUSPENDED) 12785     Wednesday, December 31 2008
Bypassing DLL injection method based in thread injectin or based in code injection in any thread diferent to main (in this case) 13719     Monday, December 15 2008
Bypassing windows hook engines which if the LoaderLock is held not executes the 12028     Sunday, December 14 2008
Windows Auxiliary API library - Internals 5275     Sunday, December 14 2008
AuxLib - Reverse engineering of Auxiliary Windows API Library (x86 and x86_64) 7812     Thursday, December 11 2008

There are 31,328 total registered users.


Recently Created Topics
[help] Unpacking VMP...
Mar/12
Reverse Engineering ...
Jul/06
let 'IDAPython' impo...
Sep/24
set 'IDAPython' as t...
Sep/24
GuessType return une...
Sep/20
About retrieving the...
Sep/07
How to find specific...
Aug/15
How to get data depe...
Jul/07
Identify RVA data in...
May/06
Question about memor...
Dec/12


Recent Forum Posts
Finding the procedur...
rolEYder
Question about debbu...
rolEYder
Identify RVA data in...
sohlow
let 'IDAPython' impo...
sohlow
How to find specific...
hackgreti
Problem with ollydbg
sh3dow
How can I write olly...
sh3dow
New LoadMAP plugin v...
mefisto...
Intel pin in loaded ...
djnemo
OOP_RE tool available?
Bl4ckm4n


Recent Blog Entries
halsten
Mar/14
Breaking IonCUBE VM

oleavr
Oct/24
Anatomy of a code tracer

hasherezade
Sep/24
IAT Patcher - new tool for ...

oleavr
Aug/27
CryptoShark: code tracer ba...

oleavr
Jun/25
Build a debugger in 5 minutes

More ...


Recent Blog Comments
nieo on:
Mar/22
IAT Patcher - new tool for ...

djnemo on:
Nov/17
Kernel debugger vs user mod...

acel on:
Nov/14
Kernel debugger vs user mod...

pedram on:
Dec/21
frida.github.io: scriptable...

capadleman on:
Jun/19
Using NtCreateThreadEx for ...

More ...


Imagery
SoySauce Blueprint
Jun 6, 2008

[+] expand

View Gallery (11) / Submit