surroundings:
Windows2000 SP4 Rollup1
use tools:
IDA V4.7
Softice
The code for this vulnerability is spoolsv.exe static loading spoolss.dll, dynamically loaded in Win32SPL.DLL by spoolss.dll: addprinterw
See you specific:
Http://blog.0x557.org/sandro/archives/2005/09/ms05043_notes.html#comments
(Thanks to the author Sandro)
First, the win32spl.dll is contained.
.TEXT: 769F7C01 PUSH 207H
.TEXT: 769F7C06 Call DLLLOCSPLMEM
.Text: 769f7c0b Mov Edi, EAX
.TEXT: 769F7C0D CMP EDI, EBX
.TEXT: 769F7C0F JZ Short_769f7c38
.Text: 769f7c11 Push DWORD PTR [ESI 4]
.TEXT: 769F7C14 Push [EBP ARG_0]
.TEXT: 769F7C17 Push Offset AWsws; LPCWSTR
.TEXT: 769F7C1C Push EDI; LPWSTR
.Text: 769f7c1d call DS: wsprintfw; overflow
.TEXT: 769F7C23 Add ESP, 10h
.TEXT: 769F7C26 PUSH EDI
.Text: 769f7c27 Call Allocsplstr; this assignment first checks the total length of the string, and it is impossible to overflow.
.TEXT: 769F7C2C MOV [EBP VAR_278], EAX
.TEXT: 769F7C32 Push EDI
.TEXT: 769F7C33 Call DLLFREESPLMEM
During the actual debugging process, this code is not available in memory.
Try remote use to add printers, still cannot guarantee the appearance of this code (sometimes none), so it is judged that there is a unloaded action after dynamic loading, and the conditions are unknown. span>
This vulnerability triggering and 039 are consistent, it is the result of an RPC call. It should be only 2000 can be used directly.
Constructing malicious packets remotely calling Addprinter, experiment, which ensures the loading of Win32SPL.DLL.
The overflow point is the call of the WSPrintfw function. The third parameter formatted is SeverName, the fourth parameter is Printername. The printername is long detected, and the SeverName is not detected. Can be used to construct super long data. Because WSPrintfW outputs up to 1024 long characters, there is a maximum of 2048 bytes that can be utilized.
Refer to some methods described online (Leven's "three kinds of ways to summarize Windows overflow", ", etc., etc. The program is just like playing patch ...
The block allocated by DLLLALLOCSPLMEM was carefully analyzed, and found that they were closely combined with some of the allocated busy blocks. Most of the blocks covered are some small pieces, store some strings, mostly the driver name of the printer. Multiple experiments have not occurred. It feels that there is no chance to write any four-byte by this allocation and release of the rear reinforcement and release stack. It seems to be relatively large related to the structure of Lookaside (refer to "Network Permeation Technology" Page293). When the reverse editorial block is allocated in the NTLALLOCATEHEAP in NTDLL, RTLFreeHeap found two comparisons on key processes:
CMP BYTE PTR [EDI 586H], 2
CMP Byte PTR [EDI 586H], 1
At this time, the value of the EDI is the Heap_ENTRY address of the current stack. The information at the offset 0x586 is not found in various information, such as "network penetration technology" Page291 only:
/ * 0x580 * / PVOID LOOKASIDE;
/ * 0x584 * / ushort lookasidelockcount;
/ * 0x588 * / Heap_uncommited_range uncommittedRanges [8];
Only missed this two bytes of information. I don't know if someone knows its meaning ... Please give a prompt:>
In the information that can be found, there is not much introduction to Lookaside, and the information that can be obtained is: more than 8 less than 1024 bytes of stacks and release, first it will be operated from the Lookaside. By the way, "Network Permeation Technology" P293 page, "said" A total of 0x1800 bytes plus an 8-byte head structure. "It seems that it is not very accurate. 8-byte head structure, very blurred concept.
The operation of the LOOKASIDE is analyzed in combination with the debugging process. Let's see if this overflow has a possibility.
The actual values mentioned in the analysis are memory information during this debugging process. Multiple experiments were consistent.
First analyze the function RTLFreeHeap. NTDLL.DLL of version 5.00.2195.7006 was disassembled with IdA.
At the entrance to the function, the comparison must be done when each stack is released:
Page: 77FCAD44 CMP BYTE PTR [EDI 586H], 2
The value of the EDI is the Heap_ENTRY address of the current pile. [EDI 586H] The actual value is 1.
(If it is 2, check the segmentIndex of the pile of heads, if there will be some operations for 0xff. It is not very clear here, because there has never been seen, did not continue to analyze. I don't know if it is related to the debug.)
It is then compared to the release symbol of the stack and the ForceFlags of the heap.
Page: 77FCB737 MOV EAX, [EBP ARG_4]
Page: 77fcb73a or eax, [EDI 10h]
Page: 77FCB73D MOV [EBP ARG_4], EAX
Page: 77FCB740 TEST EAX, 7D030F60H; actually here EAX == 0; specific meaning is not very clear.
Then check the legality of the address of the address to release the block, whether the busy position is set, whether the segmentIndex is less than 40h, and the exception is thrown. (?)
The detection block flag is placed on Heap_ENTY_SETTABLE_FLAG1-3, which is directly transferred to the merge algorithm or memory release.
Otherwise, the second comparison of [EDI 586H]:
Page: 77fcb781 CMP Byte Ptr [EDI 586H], 1Page: 77fcb788 Jnz Short Page_77fcb792
Page: 77FCB78A MOV ECX, [EDI 580H]
Page: 77FCB790 JMP Short Page_77FCB794
When satisfied:
[EDI 586H] == 1
Lookaside! = NULL
Lookasudelockcount == 0
HEAP_ENTRY_VIRTUAL_ALLOC flag is not set
Block size <1024 bytes (legendary small stack)
The stacker that will be released is added to the linked list of the LOOKASIDE corresponding location.
Otherwise transferring a merge algorithm or releasing memory.
First, use the following code to calculate the address of the Heap_lookaside in the heap:
Page: 77fcb7b4 Lea Eax, [EAX EAX * 2]
Page: 77FCB7B7 SHL EAX, 4; equivalent to * 48, Heap_lookaside size is 48 bytes
Page: 77FCB7BA Add Eax, ECX; ECX = Lookaside, calculate the corresponding Heap_lookaside address
Page: 77fcb7bc push eax
Page: 77fcb7bd call_text_77fb2c40
This function calls some of the data in Heap_lookaside to some detection and changes, eventually by:
.TEXT: 77FBB202 MOV EBP, ECX; ECX pointing to Lookaside's Heap_lookaside corresponding to this heap size head
.TEXT: 77FBB204 MOV EBX, EDX; EDX-> EBX data partial pointer to the block to be released
.Text: 77fb206 MOV EDX, [EBP 4]
.Text: 77fbb209 MOV EAX, [EBP 0]
.Text: 77fb20c MOV [EBX], EAX
.Text: 77fbb20e Mov ECX, EDX
.Text: 77fbb210 Add ECX, 10001H; Give Depth, Sequence Add 1.
.TEXT: 77FBB216 LOCK CMPXCHG8B qword PTR [EBP 0]; Head Interpolation Add Link list. Khan, this directive has never seen it ...
.TEXT: 77FBB21B JNZ Short_Text_77fbb20c
During the debugging process, the detected stacks are released, which are operations performed on the Lookaside. Moreover, the spilled block is taken directly from the Lookaside, and the LOOKASIDE position cannot be overwritten before, and the stack block that can be overwritten after the overflow is a small stack of the file name string (does not release), no idle block. It seems to have lost a chance to write any 4 bytes. It is relatively depressed here. I don't think there is anything about it, and discuss it.
During the later debugging process, another remote call triggered a read exception. This is not related to the release assignment of the stacking block, it seems that DOS still can do:> However, if you want to make further use, you have to analyze it again.
Formula91 Edited from 2005-10-09 16:57