Wednesday, November 24, 2010

Recently on a test I ran into a windows 2000 server running iis5 with the Internet Printing module enabled, I was quite surprised by this but...a shell is a shell right? Since this was on the job and I wasn't wearing my cowboy hat I fired up my windows 2000 VM (who doesn't have one of those?) and went to work. Metasploit has a module for this vuln (exploit/windows/iis/ms01_023_printer) but surprisingly it is pretty flakey. On the first run of the exploit module it did not work so I took a look at my configuration of IIS again to make sure that everything was setup properly. After confirming IIS settings I tried the module a couple more times and finally was able to get a shell. I restarted IIS and tried the module a few more times...it was still hit or miss - sometimes it would work on the first try sometimes it would take three tries, something was strange....

After breaking out immunity debugger it became clear as to why the exploit did not work everytime. According to the metasploit module the shellcode was being held at an offset of EBX and with a short assembly stub we jump to that location (see metasploit snippet below)

While this does work, it appears that sometimes the payload is not within the window and the exploit is not successful. Since we know about where in memory our payload will be when we gain control of EIP seems like a good place to use an egghunter :) I started out with an existing egghunter (http://www.hick.org/code/skape/papers/egghunt-shellcode.pdf)and modified it a little since I know about where in memory my payload is there was no sense looking everywhere for it :) A warning ahead of time - I was lazy and nop'd out the access violation check...I had plenty of bytes to burn ;) -

mov edx, ebx #ebx is the area of our starting point

or dx, 0fff

xor dx,0fff#clear out the bottom half of edx for the start of our loop

inc edx#increment edx - this is the start of our loop

nop#abbreviated nops where the original access violation check was

...

...

mov eax, 57303054#load our egg "W00T"

mov edi, edx#set edi to point at our current location in memory

scas dword ptr es:[edi]#compare our egg to dword at edi

jnz #jump back to the start of our loop (inc edx) if we didnt find the egg

scas dword ptr es:[edi]#compare our egg to the next dword for the 2nd part of the egg

jnz #jump back to the start of our loop (inc edx) if we didnt find the 2nd egg

jmp edi#jump to edi as it points to the first byte after our egg

After implementing the egghunter into the exploit I had no issues getting a shell everytime :)

Full exploit below - obviously will have to change the shellcode for it to work for you -