On Tue, 11 Feb 2003 16:11:15 -0500, Peter Huang wrote: >As I followed the trail described by Mr. Szor and Mr. Chien’s article >(http://www.peterszor.com/blended.pdf), it became clear to me the following >was the transfer point to the abused exception handler like Code Red. For a >normal C/C++ function, it was OK to assume that sub-functions will not >depend on the values of EBX, EDI, and ESI and will not abuse them. However, >that assumption was proved wrong with the Code Red exploitation and should >be corrected. One simple way is to save EBX and xor EBX out before it >transfers the rein. A more panicky way is to save and xor out all the unused >registers like EBX, EDI, and ESI for this function before it calls ECX Apparently this is exactly what happens now, except Microsoft chose to nuke eax as well (see below). But it's a bit misleading to say this made the Code Red exploitation possible. There are a numerous other ways to find your shellcode in memory without relying on having a register pointing directly at it, albeit some are more reliable than others. In this case I believe the shellcode is some way down the stack (?) in which case pointing the call ecx at some code like: retn 10h and arranging for the retn to pop a pointer to a mov eax, esp call eax would probably do the trick. You could run around all day making sure registers didn't have values that were useful to attackers, but all you'd end up doing is introducing masses of overhead and making exploitation a bit more challenging (and more satisfying). I hope you're not really suggesting that *every* function call should begin with fresh registers? It's just about justified in this case because exception handlers are one of the more common things that get overwritten. - Blazde >From XP SP1 ntdll.dll: .text:77F79B4D _RtlpExecuteHandlerForUnwind@20 proc near ; CODE XREF: RtlUnwind(x,x,x,x)+BDp .text:77F79B4D .text:77F79B4D arg_0 = dword ptr 4 .text:77F79B4D arg_4 = dword ptr 8 .text:77F79B4D arg_8 = dword ptr 0Ch .text:77F79B4D arg_C = dword ptr 10h .text:77F79B4D arg_10 = dword ptr 14h .text:77F79B4D .text:77F79B4D mov edx, offset loc_77F79BDF .text:77F79B52 lea ecx, [ecx] .text:77F79B54 .text:77F79B54 ExecuteHandler@20: ; CODE XREF: RtlpExecuteHandlerForException(x,x,x,x,x)+5j .text:77F79B54 push ebx .text:77F79B55 push esi .text:77F79B56 push edi .text:77F79B57 xor eax, eax .text:77F79B59 xor ebx, ebx .text:77F79B5B xor esi, esi .text:77F79B5D xor edi, edi .text:77F79B5F push [esp+0Ch+arg_10] .text:77F79B63 push [esp+10h+arg_C] .text:77F79B67 push [esp+14h+arg_8] .text:77F79B6B push [esp+18h+arg_4] .text:77F79B6F push [esp+1Ch+arg_0] .text:77F79B73 call ExecuteHandler2@20 .text:77F79B78 pop edi .text:77F79B79 pop esi .text:77F79B7A pop ebx .text:77F79B7B retn 14h .text:77F79B7B _RtlpExecuteHandlerForUnwind@20 endp