Securing the Java plug-in in Internet Explorer

The recent epic vulnerabilities in the Oracle Java Runtime Environment (JRE) 1.7 and how fast malware authors integrate exploits code into their kits confirm and highlight that Java is for sure the most popular attack vector used by malware authors.
I won’t expose the timeline of the recent vulnerabilities but I’ll instead provide some more fundamental readings that help understand why Java is the favorite target of malware authors:

In my opinion, we have now reach the point where just ‘keeping the JRE up-to-date’ isn’t enough anymore. Of course keeping software up-to-date is a good practice and still strongly required.
But not having a JRE currently installed is somehow more secure than just having the latest installed without a hardened configuration.
So, I’ll try to show and discuss the various ways to secure it for those who just can’t unplug it from the network as they have LOB applications running on Java in their coroporate environment.

  • Either keep it up-to-date or uninstall it
  • I’ll quote Brian Krebs who says (source) :

    If you don’t need Java, get rid of it

    If you really need to have Java, the download page is http://www.oracle.com/technetwork/java/javase/downloads/index.html

    You can use the Get-MSIZapInfo function I’ve provided in this post to find out all the JRE installed on a computer, list their version and their uninstall command

    Invoke-Command -ComputerName RemoteComputer -FilePath .\Get-MSIzap.ps1 |             
      Where-Object  {$_.Displayname -match "Java" } |             
      Select-Object -Property Displayname,UninstallString

    For each UninstallString returned, you can invoke the Windows Installer (msiexec.exe /x or msiexec.exe /uninstall) responsible for uninstalling MSI based piece of software.

  • Only execute digitally signed applets
  • To harden the Java Runtime, you can make it only load digitally signed applets as malicious java applets are probably not signed.
    This won’t be always true. The Flame malware has shown us that certificates can be brute forced. They can also be forged and stolen….
    This may not be the easiest approach as you’ll need to sign corporate applets with a publicly recognised and trusted certificate (you’ve to pay for it) and even some applets provided by Oracle are only self-signed 😦

    To achieve this, you’ll need to modify the following 4 settings:
    JRE digital signature behavior

    I’ve created a deployment.config file under C:\Windows\Sun\Java\Deployment\
    It contains the following 2 lines:

    deployment.system.config=file\:C\:/WINDOWS/Sun/Java/Deployment/deployment.properties
    deployment.system.config.mandatory=true
    

    I’ve created a deployment.properties file under C:\Windows\Sun\Java\Deployment\

    # Allow user to grant permissions to signed content
    # (true by default)
    deployment.security.askgrantdialog.show=true
    deployment.security.askgrantdialog.show.locked
     
    # Allow user to grant permissions to content from an untrusted authority.
    # (true by default)
    deployment.security.askgrantdialog.notinca=false
    deployment.security.askgrantdialog.notinca.locked
    
    # Check publisher certificate for revocation 
    # (false by default)
    deployment.security.validation.crl=true
    deployment.security.validation.crl.locked
    
    # Enable online certificate validation
    # (false by default)
    deployment.security.validation.ocsp=true
    deployment.security.validation.ocsp.locked
    

    I’ve found this configuration on this page.

  • Prevent Java from running in Internet Explorer or partially disable the JRE in the browser (if appropriate)
  • Many actors in the security field first provided a way where you needed to untick the ‘Default for Java for Browsers’
    UseJava2IExplorer

    Function Get-JREinBrowser            
    {            
    [CmdletBinding()]            
    param(            
                
        [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]                        
        [Alias("CN","__SERVER","IPAddress")]                        
        [system.string[]]$ComputerName = ".",            
                
        [parameter()]            
        [System.Management.Automation.PSCredential]$Credential            
                    
    )            
    Begin {            
        # Make sure we run as admin                        
        $usercontext = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()                        
        $IsAdmin = $usercontext.IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")                                           
        if (-not($IsAdmin))                        
        {                        
            Write-Warning "Must run powerShell as Administrator to perform these actions"                        
            return                        
        }            
        # Define some registry constants                        
        $HKLM = 2147483650            
        $x86MainKey = 'SOFTWARE\Wow6432Node\JavaSoft\Java Plug-in'            
        $x64MainKey = 'SOFTWARE\JavaSoft\Java Plug-in'            
    }                
    Process {            
        $ComputerName | ForEach-Object -Process {            
            $TargetComputer = $_            
            # Prepare a default HT                        
            $wmiHT = @{                        
                ErrorAction = "Stop";                        
            }                        
            Switch ($TargetComputer)            
            {            
                {$_ -eq ($Env:Computername)} {$IsRemoteComputer = $false ; break}            
                {$_ -eq "."}                 {$IsRemoteComputer = $false ; break}            
                {$_ -eq "::1"}               {$IsRemoteComputer = $false ; break}            
                {$_ -eq "127.0.0.1"}         {$IsRemoteComputer = $false ; break}            
                {$_ -eq "localhost"}         {$IsRemoteComputer = $false ; break}            
                default {            
                    $IsRemoteComputer = $true            
                }                        
            }            
            if($IsRemoteComputer)            
            {            
                Write-Verbose -Message "Detecting $TargetComputer as a remote computer"            
                $wmiHT += @{             
                    Authentication = 6;            
                    Impersonation  = 3;            
                    Computername   = $TargetComputer;            
                }            
                if ($Credential)            
                {            
                    $wmiHT += @{ Credential = $Credential }            
                }            
                            
            } else {            
                Write-Verbose -Message "Detecting $TargetComputer as a local computer"            
            }            
                        
            # Enumerate            
            $x64MainKey,$x86MainKey | ForEach-Object -Process {            
                $Key = $_            
                try            
                {            
                    Invoke-WmiMethod -Path "ROOT\DEFAULT:StdRegProv" -Name EnumKey -ArgumentList $HKLM,$Key @wmiHT            
                } catch {            
                    Write-Warning -Message "Failed to query WMI on $TargetComputer because $($_.Exception.Message)"            
                }            
            }  | ForEach-Object -Process {            
                if ($_.ReturnValue -eq 0)            
                {            
                    # The key exists            
                    $_.sNames | ForEach-Object -Process {            
                        $Version = $_            
                        $Key = "$Key\$Version"            
                        Write-Verbose -Message "Attempting to get version under $Key on $TargetComputer"            
                                    
                        try {            
                            Invoke-WmiMethod -Path "ROOT\DEFAULT:StdRegProv" -Name GetDWORDValue -ArgumentList $HKLM,$Key,"UseJava2IExplorer" @wmiHT             
                        } catch {            
                            Write-Warning -Message "Failed to get the browser flag for $Verion under $Key on $TargetComputer because $($_.Exception.Message)"            
                        }            
                    } | ForEach-Object -Process {            
                        $result = $_.ReturnValue            
                        $value  = $_.uValue            
                        Switch ($result)            
                        {            
                            0 {            
                                switch ($value)            
                                {            
                                    0 {            
                                        New-Object -TypeName PSObject -Property @{            
                                            Version = $Version            
                                            Key = $Key            
                                            ComputerName = $TargetComputer            
                                            Status = 'Disabled'            
                                        }            
                                    }            
                                    1 {            
                                        New-Object -TypeName PSObject -Property @{            
                                            Version = $Version            
                                            Key = $Key            
                                            ComputerName = $TargetComputer            
                                            Status = 'Enabled'            
                                        }            
                                    }            
                                    default {            
                                        New-Object -TypeName PSObject -Property @{            
                                            Version = $Version            
                                            Key = $Key            
                                            ComputerName = $TargetComputer            
                                            Status = 'Unknown'            
                                        }            
                                    }            
                                }            
                            }            
                            2 {            
                                Write-Warning -Message "DWORD value UseJava2IExplorer doesn't exist under $Key on $TargetComputer"            
                            }            
                            default {            
                                Write-Warning -Message "Querying DWORD value UseJava2IExplorer under $Key on $TargetComputer returned $result"            
                            }            
                        }            
                    }            
                } elseif ($_.ReturnValue -eq 2) {            
                    # The key doesn't exist            
                    Write-Warning -Message "$Key not found on $TargetComputer"            
                } else {            
                    Write-Warning -Message "Quering $Key on $TargetComputer returned $($_.ReturnValue)"            
                }            
            }            
        }                      
    }            
    End {}            
    }            
                
    Function Set-JREinBrowser            
    {            
    [CmdletBinding()]            
    param(            
                
        [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]                        
        [Alias("CN","__SERVER","IPAddress")]                        
        [system.string[]]$ComputerName = ".",            
                
        [parameter()]            
        [System.Management.Automation.PSCredential]$Credential,            
                    
        [parameter(ParameterSetName="Enable")]            
        [switch]$Enable=$false,            
                    
        [parameter(ParameterSetName='Disable')]            
        [switch]$Disable=$false                
                
    )            
    Begin {            
                
        switch ($PsCmdlet.ParameterSetName)            
        {            
            Enable {            
                if ($Enable) { $Action = 'Enable' ; break}            
            }            
            Disable {            
                if ($Disable) { $Action = 'Disable' ; break}            
            }            
            default {             
                # We will never get here because if both parametersets/switch are specified or missing            
                # it will throw an error saying: 'Parameter set cannot be resolved using the specified named parameters.'            
            }            
        }            
        # Make sure we run as admin                        
        $usercontext = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()                        
        $IsAdmin = $usercontext.IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")                                           
        if (-not($IsAdmin))                        
        {                        
            Write-Warning "Must run powerShell as Administrator to perform these actions"                        
            return                        
        }            
        # Define some registry constants                        
        $HKLM = 2147483650            
        $x86MainKey = 'SOFTWARE\Wow6432Node\JavaSoft\Java Plug-in'            
        $x64MainKey = 'SOFTWARE\JavaSoft\Java Plug-in'            
    }                
    Process {            
        $ComputerName | ForEach-Object -Process {            
            $TargetComputer = $_            
            # Prepare a default HT                        
            $wmiHT = @{                        
                ErrorAction = "Stop";                        
            }                        
            Switch ($TargetComputer)            
            {            
                {$_ -eq ($Env:Computername)} {$IsRemoteComputer = $false ; break}            
                {$_ -eq "."}                 {$IsRemoteComputer = $false ; break}            
                {$_ -eq "::1"}               {$IsRemoteComputer = $false ; break}            
                {$_ -eq "127.0.0.1"}         {$IsRemoteComputer = $false ; break}            
                {$_ -eq "localhost"}         {$IsRemoteComputer = $false ; break}            
                default {            
                    $IsRemoteComputer = $true            
                    Write-Verbose -Message "Computer is a remote target" -Verbose            
                }                        
            }            
            if($IsRemoteComputer)            
            {            
                Write-Verbose -Message "Detecting $TargetComputer as a remote computer"            
                $wmiHT += @{             
                    Authentication = 6;            
                    Impersonation  = 3;            
                    Computername   = $TargetComputer;            
                }            
                if ($Credential)            
                {            
                    $wmiHT += @{ Credential = $Credential }            
                }            
            } else {            
                Write-Verbose -Message "Detecting $TargetComputer as a local computer"            
            }            
                        
            # Enumerate            
            $x64MainKey,$x86MainKey | ForEach-Object -Process {            
                $Key = $_            
                try            
                {            
                    Invoke-WmiMethod -Path "ROOT\DEFAULT:StdRegProv" -Name EnumKey -ArgumentList $HKLM,$Key @wmiHT            
                } catch {            
                    Write-Warning -Message "Failed to query WMI on $TargetComputer because $($_.Exception.Message)"            
                }            
            }  | ForEach-Object -Process {            
                if ($_.ReturnValue -eq 0)            
                {            
                    # The key exists            
                    $_.sNames | ForEach-Object -Process {            
                        $Version = $_            
                        $Key = "$Key\$Version"            
                        Write-Verbose "Attempting to change values under $Key on $TargetComputer"            
                        Switch ($Action)            
                        {            
                            Enable { $Value = [int32]1}            
                            Disable { $Value = [int32]0}            
                            default {}            
                        }            
                        Write-Verbose -Message "Action is $action so value to set is $Value"            
                        try {            
                            $result = Invoke-WmiMethod -Path "ROOT\DEFAULT:StdRegProv" -Name SetDWORDValue -ArgumentList $HKLM,$Key,"UseJava2IExplorer",$Value @wmiHT            
                        } catch {            
                            Write-Warning -Message "Failed to set $Value on valuename UseJava2IExplorer under $Key on $TargetComputer"            
                        }                                  
                        if ($result)            
                        {            
                            if ($result.ReturnValue -eq 0)            
                            {            
                                    'Successfully changed Java RunTime browser integration on {0}' -f $TargetComputer            
                            } else {            
                                    'Failed to change Java RunTime browser integration on {0}' -f $TargetComputer            
                                    'Returned value was {0}' -f ($result.ReturnValue)            
                            }            
                
                        } else {            
                            Write-Warning -Message "Failed"            
                        }            
                    }            
                } elseif ($_.ReturnValue -eq 2) {            
                    # The key doesn't exist            
                    Write-Warning -Message "$Key not found on $TargetComputer"                            
                } else {            
                    Write-Warning -Message "Quering $Key on $TargetComputer returned $($_.ReturnValue)"            
                }            
            }            
        }                      
    }            
    End {}            
    }

    Here’s how to use the 2 above functions

    $cred = (Get-Credential)            
    "RemotePC" | Get-JREinBrowser -Credential $cred -Verbose            
    "RemotePC" | Set-JREinBrowser -Enable -Verbose -Credential $cred            
    "RemotePC" | Set-JREinBrowser -Disable -Verbose -Credential $cred            
    

    However the above step wasn’t enough as there are various ways of invoking Java inside Internet Explorer.

    Microsoft provided the recommended guidance on how to disable the Java web plug-in in Internet Explorer

    Java is a unique form of extensibility because it can be invoked in two ways:
    By using an applet element
    By using an object element that has a CLSID of a Java Virtual Machine (JVM)
    These two invocation methods are subject to different security controls.

    The first step consists in disabling Applets by setting the Java permissions to ‘Disable’

    URL action flag name: URLACTION_JAVA_PERMISSIONS
    Security setting UI : Java permissions (not visible by default in the UI)
    Numeric name : 1C00
    Possible values are:
    “High safety”=0x00010000
    “Medium safety”=0x00020000
    “Low safety”=0x00030000
    “Custom”=0x00800000
    “Disable Java”=0x00000000

    Microsoft recommends to set it to 0x0 on the Internet zone (#3)

    To understand security zones and from where the URLACTION_JAVA_PERMISSIONS flag (1C00) is being read and applied, I recommend to read the following 2 pages:

    Setting it on the CurrentUser hive (HKCU) can be a non sense if you’re in a corporate environment and already use Group policy to control zone templates and settings.

    The second step consists in setting the kill-bit on Java Plug-in CLSIDs to block OBJECT tag invocation.

    Before setting kill-bits I recommend reviewing the following setting, especially in the Internet zone (3) as the following KB article states that:

    after the kill bit is set for an ActiveX control, that control is not called by Internet Explorer at all unless the Initialize and script ActiveX controls not marked as safe option is enabled in Internet Explorer.

    URL action flag name: URLACTION_ACTIVEX_OVERRIDE_OBJECT_SAFETY
    Security setting UI : Initialize and script ActiveX controls not marked as safe
    Numeric name : 1201
    Possible values:
    “Enable”=0x00000000
    “Disable”=0x00000003
    “Prompt”=0x00000001

    Note that the URLACTION_ACTIVEX_OVERRIDE_OBJECT_SAFETY flag is disabled(0x3) in the Internet zone. This prevents bypassing killbits. So, Killbits set are actually enforced in the Internet zone.

    Then we need to identify all the CLSIDs related to the Java Plug-in, so we do:

    (Get-ChildItem HKLM:\SOFTWARE\Wow6432Node\Classes\CLSID -Recurse) | ForEach-Object -Process {            
        if ($_.PSIsContainer -and ($_.PSChildName -match [regex]'(?^\{[A-Za-z0-9]{8}\-[A-Za-z0-9]{4}\-[A-Za-z0-9]{4}\-[A-Za-z0-9]{4}\-[A-Za-z0-9]{12}\})'))            
        {            
            try            
            {            
                (Get-ItemProperty $_.PSPath -Name '(default)' -ErrorAction Stop)            
            } catch {            
            }            
        }            
    } | ForEach-Object -Process {            
        if ($_.'(default)' -match "Java Plug-in")            
        {            
            $_            
        }            
    } | Format-Table -AutoSize -Wrap -Property @{l='CLSID';e={$_.PSChildName}},@{l='DisplayName';e={$_.'(default)'}}

    We end up with the following long list…
    All JRE CLSID

    I’ve also written 3 helper functions to get, set or clear the kill-bit on a specific set of CLSIDs

    Function Get-KillBit             
    {            
    [CmdletBinding()]            
    param(            
    # By GUID            
    [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]                        
    [string[]]$GUID            
    )            
    Begin{            
        $x86='Software\Wow6432Node'            
        $x64='Software'            
    }            
    Process{            
        $GUID | ForEach-Object -Process {            
            $GUIDitem = $_            
            Write-Verbose "Testing GUID $GUIDitem"            
            $x86,$x64 | ForEach-Object {            
                Write-Verbose "Testing Hive $_"            
                $HiveLocation = $_            
                $flag = $null            
                try {            
                    $flag = Get-ItemProperty -Path "HKLM:\$HiveLocation\Microsoft\Internet Explorer\ActiveX Compatibility\$GUIDitem" -Name 'Compatibility Flags' -ErrorAction Stop            
                } catch {            
                    Write-Warning "Failed because $($_.Exception.Message)"            
                    return            
                }            
                New-Object -TypeName PSobject -Property @{            
                    GUID = $GUIDitem            
                    Path = $flag.PSPath            
                    Value = $flag.'Compatibility Flags'            
                    HexValue = -join ('0x',('{0:X0}' -f $flag.'Compatibility Flags'))            
                    DisplayName = (Get-ItemProperty -Path "HKLM:\$HiveLocation\Classes\CLSID\$GUIDitem" -Name '(default)' -ErrorAction Silentlycontinue).'(default)'            
                }            
            }            
        }            
    }            
    End{}            
    }            
                
    Function Set-KillBit             
    {            
    [CmdletBinding()]            
    param(            
    # By GUID            
    [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]                        
    [string[]]$GUID=$null            
    )            
    Begin{            
        # Make sure we run as admin                        
        $usercontext = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()                        
        $IsAdmin = $usercontext.IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")                                           
        if (-not($IsAdmin))                        
        {                        
            Write-Warning "Must run powerShell as Administrator to perform these actions"                        
            return                        
        }            
        $x86='Software\Wow6432Node'            
        $x64='Software'            
    }            
    Process{            
        $GUID | ForEach-Object -Process {            
            $GUIDitem = $_            
            Write-Verbose "Handling GUID $GUIDitem"            
            $x86,$x64 | ForEach-Object {            
                Write-Verbose "Setting it in hive $_"            
                $HiveLocation = $_            
                $flagged = $null            
                try {            
                                
                    if (-not(Test-Path "HKLM:\$HiveLocation\Microsoft\Internet Explorer\ActiveX Compatibility\$GUIDitem"))            
                    {            
                        New-Item -Path "HKLM:\$HiveLocation\Microsoft\Internet Explorer\ActiveX Compatibility" -Name $GUIDitem -Force -ErrorAction Stop | Out-Null            
                        New-ItemProperty -Path "HKLM:\$HiveLocation\Microsoft\Internet Explorer\ActiveX Compatibility\$GUIDitem" -PropertyType DWORD -Name 'Compatibility Flags' -Value 1024 -Force | Out-Null            
                    } else {            
                        Set-ItemProperty -Path "HKLM:\$HiveLocation\Microsoft\Internet Explorer\ActiveX Compatibility\$GUIDitem" -Name 'Compatibility Flags' -Value 1024 -Type DWORD -Force -ErrorAction Stop            
                    }            
                    $flagged = $true            
                } catch {            
                    $flagged = $false            
                    Write-Warning "Failed because $($_.Exception.Message)"            
                }            
                if ($flagged)            
                {            
                    Write-Verbose -Message "Successfully set kill-bit on $GUIDitem in hive $HiveLocation"            
                } else {            
                    Write-Verbose -Message "Failed to set kill-bit on $GUIDitem in hive $HiveLocation"            
                }            
            }            
        }            
    }            
    End{}            
    }            
                
    Function Clear-KillBit             
    {            
    [CmdletBinding()]            
    param(            
    # By GUID            
    [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]                        
    [string[]]$GUID=$null            
    )            
    Begin{            
        # Make sure we run as admin                        
        $usercontext = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()                        
        $IsAdmin = $usercontext.IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")                                           
        if (-not($IsAdmin))                        
        {                        
            Write-Warning "Must run powerShell as Administrator to perform these actions"                        
            return                        
        }            
        $x86='Software\Wow6432Node'            
        $x64='Software'            
    }            
    Process{            
        $GUID | ForEach-Object -Process {            
            $GUIDitem = $_            
            Write-Verbose "Handling GUID $GUIDitem"            
            $x86,$x64 | ForEach-Object {            
                Write-Verbose "Setting it in hive $_"            
                $HiveLocation = $_            
                $flagged = $null            
                try {            
                    if (Test-Path "HKLM:\$HiveLocation\Microsoft\Internet Explorer\ActiveX Compatibility\$GUIDitem")            
                    {            
                        Remove-Item -Path "HKLM:\$HiveLocation\Microsoft\Internet Explorer\ActiveX Compatibility\$GUIDitem" -Force -ErrorAction Stop | Out-Null            
                    } else {            
                        # already removed            
                    }            
                    $flagged = $true            
                } catch {            
                    $flagged = $false            
                    Write-Warning "Failed because $($_.Exception.Message)"            
                }            
                if ($flagged)            
                {            
                    Write-Verbose -Message "Successfully cleared kill-bit on $GUIDitem in hive $HiveLocation"            
                } else {            
                    Write-Verbose -Message "Failed to clear kill-bit on $GUIDitem in hive $HiveLocation"            
                }            
            }            
        }            
    }            
    End{}            
    }            
    

    To use the above functions, you can for example do:

                
    #            
    # Set the kill-bit on any Java related CLSID            
    #            
                
    (Get-ChildItem HKLM:\SOFTWARE\Wow6432Node\Classes\CLSID -Recurse) | ForEach-Object -Process {            
        if ($_.PSIsContainer -and ($_.PSChildName -match [regex]'(?^\{[A-Za-z0-9]{8}\-[A-Za-z0-9]{4}\-[A-Za-z0-9]{4}\-[A-Za-z0-9]{4}\-[A-Za-z0-9]{12}\})'))            
        {            
            try            
            {            
                (Get-ItemProperty $_.PSPath -Name '(default)' -ErrorAction Stop)            
            } catch {            
            }            
        }            
    } | ForEach-Object -Process {            
        if ($_.'(default)' -match "Java Plug-in")            
        {            
            $_            
        }            
    } | ForEach-Object -Process {            
        Set-KillBit -GUID $_.PSChildName            
    }             
                
    #            
    # Get all the kill-bits set            
    #            
                
    (Get-ChildItem HKLM:\SOFTWARE\Wow6432Node\Classes\CLSID -Recurse) | Where-Object {            
        $_.PSIsContainer -and ($_.PSChildName -match [regex]'(?^\{[A-Za-z0-9]{8}\-[A-Za-z0-9]{4}\-[A-Za-z0-9]{4}\-[A-Za-z0-9]{4}\-[A-Za-z0-9]{12}\})')            
    } | ForEach-Object -Process {                
            try {            
                (Get-ItemProperty $_.PSPath -Name '(default)' -ErrorAction Stop)            
            } catch {}            
    } | Where-Object  {($_.'(default)' -match "Java Plug-in")} | ForEach-Object -Process {            
         Get-KillBit -GUID $_.PSChildName            
    }  | Sort-Object -Descending -Property GUID | Select-Object -Property GUID,DisplayName,HexValue            
                
    #             
    # Clear some kill-bit on a subset of CLSIDs            
    #             
                
    # Define a array of whitelisted CLSIDs            
    $allowed = "{CAFEEFAC-FFFF-FFFF-FFFF-ABCDEFFEDCBA}",            
    "{CAFEEFAC-0016-0000-0035-ABCDEFFEDCBC}",            
    "{CAFEEFAC-0016-0000-0035-ABCDEFFEDCBB}",            
    "{CAFEEFAC-0016-0000-0035-ABCDEFFEDCBA}",            
    "{8AD9C840-044E-11D1-B3E9-00805F499D93}"            
    # Clear            
    $allowed | Clear-KillBit -Verbose            
    

    In other words, Powershell allows us to dynamically disable all the Java Plug-ins’ CLSIDs present on a computer instead of having (too many) CLSIDs hardcoded in a .reg file.

    Best of all, here are the most comprehensive articles on what can be done in the Internet Explorer configuration to control and harden the Java behavior:

    So, if you want to permit Java to run only in the Intranet and Trusted Sites zones:
    Adjust the URLAction for the Internet Zone to Disable
    Remove the * from the Per-Site list of the ActiveX Control
    Step #1 will ensure that only Intranet Zone and Trusted Zone sites may load Java for APPLET Tags.
    Step #2 will ensure that the Java Plug-in will not load as an OBJECT on Internet Zone sites; a notification will be shown instead.
    Because Intranet and Trusted Sites ignore the Per-Site ActiveX list, you won’t see any additional warnings on those sites.

    I’d like to mention other interesting articles on this subject:

  • Protecting yourself from CVE-2012-4681 Java exploits
  • The Kill-Bit FAQ: Part 1 of 3
  • The Kill-Bit FAQ: Part 2 of 3
  • The Kill-Bit FAQ: Part 3 of 3
  • Managing ActiveX Controls
  • How to stop an ActiveX control from running in Internet Explorer
  • Flags behavior of registered Microsoft ActiveX controls
  • Advertisements