Conexant Keylogger



You may have heard that HP have been found to have some laptops that were shipping with what is in effect a keylogger!  The affected models have a Conexant audio chip whose driver includes hotkey functionality for microphone muting.  Unfortunately this was left in debugging mode and as a result logged all keypresses to a file locally!  HP’s official security bulletin is here.

Some of our laptops were affected and our antivirus started detecting it as “Conexant MicTray Keylogger”.  Just the thing to scare our users with after the recent news over the WannaCry v2 ransomware…

Rather than push a 200MB driver update to them all, I shut them up remotely with the following little batch file I pushed out over SCCM.

@echo off
taskkill.exe /im:MicTray.exe /f >nul 2>&1
taskkill.exe /im:MicTray64.exe /f >nul 2>&1
del /F c:\Windows\System32\MicTray.exe >nul 2>&1
del /F c:\Windows\System32\MicTray64.exe >nul 2>&1
del /F "c:\Program Files\Conexant\Install\Audio\MicTray\MicTray\MicTray.exe" >nul 2>&1
del /F "c:\Program Files\Conexant\Install\Audio\MicTray\MicTray\MicTray64.exe" >nul 2>&1
del /F c:\Users\Public\MicTray.log >nul 2>&1

In retrospect, I’m glad that’s the solution I took, as the first update HP released to fix the issue apparently didn’t even remove the functionality, it just turned it off – but it could then be re-enabled with a registry value change!  Since our users don’t use the mics on their laptops, I’m leaving the thing deleted as above.

Interesting PowerShell Remoting Issue



I saw an odd error message today whilst testing PSRemoting on a couple of PCs, a process which involved my disabling and re-enabling it.  It brought up an interesting problem I thought worth sharing.

I have a Group Policy Object with a Computer Startup script that looks for missing PowerShell Remoting Endpoints (i.e. PSSession Configurations such as “Microsoft.PowerShell”) and re-runs Enable-PSRemoting if required to fix them.  If you look at my earlier post, you’ll see why I ended up with such a config.  I thought this would ensure remoting would always work for PCs in this particular Organisational Unit.

Here’s the error I got trying to remote to one PC that had had Remoting expressly disabled but had then been put back in the OU that should have re-enabled it again but clearly hadn’t done so successfully:


Testing WSMan connectivity showed that side of things was working:


Both expected Session Configurations were also present but I decided to investigate them closer with the following command.

Get-PSSessionConfiguration | Format-List -Property *

Going down each property in turn on the two PCs I spotted a difference in the rather unfriendly SecurityDescriptorSddl property.  Fortunately this is interpreted into something more meaningful in the Permission property which of course was the last one of over 30 in the list!  Picking that one out, here’s how it looked on a working PC:


And here’s how it looked on the faulty PC:


This Denied Network access entry could also be seen using the GUI equivalent:


I thought it odd that there was a Deny entry in there but I fixed it with an Enable-PSRemoting again (which would actually would have been the first fix I’d have tried, except I wanted to try and work out exactly why it was broken).

The explanation of course is that I hadn’t looked into the details of exactly what Disable-PSRemoting might do.  From the documentation comes the phrase:

Disable-PSRemoting blocks remote access to all session configurations on the local computer. This prevents remote users from creating temporary or persistent sessions to the local computer. Disable-PSRemoting does not prevent users of the local computer from creating sessions (“PSSessions”) on the local computer or remote computers.

If you look at the Examples in that cmdlet’s help, you will see how the Network Deny we’ve seen gets put in.  It’s more of a Deny-PSRemoting than a Disable-PSRemoting!

Looks as though I need to alter my Startup script to make a check for these denies as well as just a check to see if the endpoints exist, as a Disable-PSRemoting makes them still exist, just no longer work remotely…!

Windows 10 build 1703 RSAT Fail



I upgraded my Windows 10 Pro Build 1607 work PC to Build 1703 this week.  At the start of the install process, it warned me that it was going to remove a display language and I’d have to reinstall it afterwards.  I’m using en-GB.

Once the upgrade was done, I found that RSAT was no longer installed and its pinned shortcuts on Start were blank with odd text across them.  I reinstalled RSAT (incidentally I’ve read that there will not be a Build 1703 of RSAT and that you just use Build 1607).  It reinstalled suspiciously quickly and the problem remained; including after reboot.

I remember similar issues with previous builds involving having to get the en-US display language installed again as a fix.  Unfortunately I could not persuade it to do so – the relevant part of the GUI kept saying that I needed to connect to the Internet – despite Windows Update working fine!  I think our web filtering proxy software was probably blocking its access in some way.

I eventually had to give up and leave it for another day and so rolled back to Build 1607 (which was quite a quick and painless process).

Later, back at home, I installed the en-US Display Language into my home PC and used Process Monitor to see exactly what got downloaded and installed.  The file was:


I took that CAB file to work today and re-upgraded my PC to Build 1703.  I then ran LPKSETUP.exe which you use to install Display Languages:


After browsing to the CAB file it happily reinstalled the en-US pack, though this was quite a slow process:


Once done, the problem with my shortcuts remained, so I reinstalled RSAT and this time all my pinned shortcuts came back to life (without a further reboot).

I did try and reproduce all this again in a VM at home, hoping to get some more screenshots and to sniff out the URL too but the problem did not occur.  I’m guessing it must be something to do with differences in the locale of the ISO used between work and home.

I hope the above helps someone else!


Why Learn PowerShell?

In case you’re wondering why PowerShell is worth learning, here for example are problems I quickly solved at work just today using only basic PowerShell:

  1. List all enabled Active Directory user accounts with no email address configured.
  2. Given a spreadsheet of 600+ accounts with valid email addresses now listed beside them, update AD user account properties accordingly.
  3. Given a list of users who have left the organisation,  disable their AD accounts and move them to a specific OU (for deletion in the future).
  4. Search an Organisational Unit full of disabled user accounts for any that were still in a particular group.

These tasks were all trivial in PowerShell!  What are you waiting for?  Get learning!

PayPal’s Emails Encourage Dangerous Habits


, ,

I’ve recently got fed up going round and round in circles with PayPal trying to get them to admit that their own emails are not actually phishing scams!

Yes, you read that right.  The problem is that PayPal’s own email campaigns encourage users to click on links to domains that look to the suspicious eye like a phishing scam.  PayPal’s own spoof detection service identifies these emails as “likely fraudulent” and if you contact PayPal directly, they’ll repeatedly deny all knowledge of the domains in question being their own.

Let’s have a look into this sorry story…

Firstly, here’s the start of a typical example email, sent to me on March 3rd from “”:


Unlike normal phishing emails, this email addresses me by my full name and is literate.  The problem comes if you assess the target domain of the “Log In Now” button.  Here’s the tooltip:


Destination address “” looks suspiciously like a typical phishing domain.  Any security-aware user ought not to click on such a link.  I don’t particularly want to be visiting a site that for all I know might be serving up ransomware via an exploit kit!

I had a look online and found discussion at  which included references to this target domain with users asking after it because they were suspicious.  Here’s what one user said:


And another:


And a third:


And the response from the PayPal moderator? (Details hidden to save the blushes.)


I decided to dig around a bit.  A WHOIS on the domain said it is registered to PayPal (via a company called MarkMonitor who protect brands):


Then I looked at the SSL certificate of the domain:


That is an Extended Validation SSL certificate issued by DigiCert to PayPal.

At this point I was sure it had to be legitimate and so contacted PayPal support and told them the story so far.  In my message I included the following:

On the assumption that this is indeed genuine, can I suggest that perhaps you ensure that all emails you send with links in, go only to or! Otherwise, you’re making it very difficult for users to tell what is legitimate and what is not.

For my trouble I got a standard automated reply with general educational info on phishing emails and the comment, “If we haven’t answered your question, please reply to this email and our team will answer you as soon as possible”.

If they’d bothered to read my email properly they’d have known I had gone beyond that stage.  This sort of automated response irrespective of what you’ve said – especially since you have to reply to it to even get a human response – is the ideal way to frustrate your customers!

I also forwarded the email to their spoof detection service (in my case  Here’s the reply I got:


Unbelievable!  And how indecisive is “likely fraudulent” anyway?!  I tested the actual link in the email by running Chrome inside Sandboxie for added safety.  It redirected to which suggests all is well.  Replying to the automated support email, I gave them the newer information and the verdict of their spoof service and asked them to look into it.  I got the following response.  I’ve just shown the start as you’ll get the idea…


Feeling increasingly exasperated, I emailed back and said that either the domain was legitimately theirs, or DigiCert had issued an EV SSL certificate in their name to a third party, “which would be a major security issue and absolutely catastrophic for their business too!”.  I encouraged them to escalate it.

The reply asked for me to forward them the email:


I tried to cut a corner as I’d deleted the email by then:

Please can youi simply clarify whether a link to is a valid destination address to have in an email from PayPal.  There is every sign that it is (the domain appears to be registered to PayPal!) …

The reponse was, shall we say, “frustrating”:


I emailed straight back:

I have not said I received an email saying there is suspicious activity in my account.  You too have now said that the email is not from PayPal.  In that case, please can you explain why the link it asks me to log in to is at a domain formally registered to PayPal and with a PayPal SSL certificate on it?

Needless to say, every single message was from a different person – no attempt to take ownership of a problem and run with it.

I eventually got a phonecall and was passed from person to person three times.  Everyone sounded quite interested in and intrigued by the story and the technical details.  I’m sure one of them said they were basically told to deny any domain that did not end or but he was clearly struggling to deny the domain I was telling him about!  I was told I would hear back.  I left the phonecall feeling happier that this would be escalated to someone in the know.  A few days later I prodded them for an update and told them I’d had another similar email.  I finally got a new reply in my PayPal message centre.  It took things to a whole new level of ridiculousness:


That last sentence shows how much I’ve been wasting my time.  How can they possibly say a subdomain of is not theirs?  I first decided to prove that that domain could receive email:


As we will see in a minute, the result was quite instructive.  If you also do a SmartWHOIS to find who is responsible for the IP block that the domain is on, you get the following:


“Epsilon Data Mangement” owns the IP block and judging by the Mail Exchanger record name, runs the mail server and presumably is the explanation for the “epl.” at the start of the main domain name that set this hunt all off.  So, who are Epsilon Data Management?  Here’s part of what their website says they do:


This all sounds very like the sort of emails that contain these links!

I’d sent one more email to PayPal which included this rebuttal to their latest claim:

I’ve confirmed that there is a DNS MX Record for domain “” which shows it is a legitimate domain that can receive email. Also, since it is a child domain of, it MUST by definition belong to the same owners as “”!  So how can you say it does not belong to PayPal?

 I got one more message from PayPal before I gave up in disgust:


After some more hunting around the PayPal site, I found one more thing of interest – on PayPal’s “List of Third Parties (other than PayPal Customers) with Whom Personal Information May be Shared” page:


Quote: “To execute outbound communciation campaigns including but not limited to email and push notifications.”

The story doesn’t end here.  I tried taking it to Twitter and sending Direct Messages to @AskPayPal (PayPal Support).  I gave a very brief version of the case and at their request sent a screenshot of one of the emails – with the tooltip link visible.  I also sent a screenshot of the SSL certificate.  I got a much more positive response:


I provided some more info, including about Epsilon.  I got another reply:


And the next reponse, which unfortuantely was from someone else?


I managed not to die of frustration when told to forward it to the spoof service again.  But then, there was final bit of acceptance:


And that’s where it ends. …

And this is a company I’m entrusting with access to my money?  The left hand doesn’t seem to know what the right hand is doing – in fact, it just denies all knowledge of its existence despite all evidence to the contrary.  That coupled with the generally poor support experience leaves me … shall we say … “not overly-enamoured” of PayPal now.

The Twitter chat had closed with the following.


 I couldn’t bring myself to click on it…

Physical RAM full on File Server


Had an interesting situation today on an old FileServer that’s still on Server 2008 R2 and only has 4GB of RAM.  While BackupExec is doing a full backup, the server absolutely crawls and becomes sluggish for users.  I struggled to RDP to it to investigate – it kept timing out.

Here’s what I eventually saw in Task Manager:


As you can see from the bottom of the window, Physical Memory is 91% used but with the processes sorted by memory use, the greediest is merely the AntiVirus with not even a quarter of a GB consumed.

The Performance tab was not much more revealing:


Here you can see that the total Commited RAM was not even 1.5GB of the 8GB limit (physical RAM + paging file).  Still though, you can see the RAM is well and truly taken up by something.  Incidentally, network traffic was minimal – indeed the backup was struggling at a slow speed.

Next stop was Sysinternals’ Process Explorer’s System Information window:


This reveals (at bottom left) that there is nearly 3GB of physical RAM used by the cache.

Finally, I loaded Sysinternals’ RAMMap:


This shows quite clearly that the RAM is used by an entry labelled “Metafile”.  This refers to NTFS Metadata such as the MFT (Master File Table) amongst other things.  Given that a 1TB data volume was being backed up, I guess it’s not surprising that so much NTFS Metadata is being accessed.

I found online that you can verify the size of the MFT using fsutil.exe:


Note the line “Mft Valid Data Length”.  You can convert that to decimal by entering into Windows Calculator.  I couldn’t bring myself to screenshot the awful Mickey Mouse App version on Windows 10, so here it is on the server:


After entering Programmer mode and selecting the Hex radiobutton, you type in the value and then click Dec to convert it to Decimal.


That gives a value which when converted from bytes equates to about 2.3GB for the MFT alone.

Obviously, we have to feed this server more RAM and see how it gets on…!

Read-Only USB Flash Drive Issue


I came across an interesting issue with a Kingston DataTraveler Micro USB Flash Drive yesterday that I thought worth sharing.

Initially, I spotted an error in the System Event Log – “{Delayed Write Failed} Windows was unable to save all the data for the file … The data has been lost. This error may be caused by a failure of your computer hardware or network connection. Please try to save this file elsewhere.”  Since I hadn’t been yanking USB drives out without formally ejecting them, this was a little concerning.  Here’s the full error:


A scroll through the System Event Log was less than reassuring, with many errors with Source disk and Ntfs:


The error from source disk was “An error was detected on device \Device\Harddisk2\DR7 during a paging operation.”  It’s not immediately clear how to tally “\Device\Harddisk2\DR7” to a physical drive in the PC:


The error from source Ntfs was “The system failed to flush data to the transaction log.  Corruption may occur in VolumeId: E:, DeviceName: \Device\HarddiskVolume11. (The I/O device reported an I/O error.)”  That’s a more helpful error as it gives a drive letter that corresponded to one of my USB Flash Drives:


On opening the Disk Management MMC, it can be seen that the Disk number shown on the left side of the GUI that holds the partition bearing this E: drive matches the Harddisk number (2) in the disk event log entry.  So the two errors match up:


My first thought was to try to scan the drive for any errors and fix them.  The computer then bizarrely claimed that “The disk is write protected.”  This is not the sort of USB Drive that has a physical write-protect switch:


I then wondered if my AntiVirus was interfering, so I tried disabling both it and my AntiExploit software but to no avail.  After some reading around, I discovered that diskpart can be used to view and alter the Read-Only status of a drive via its detail disk command.  I first use list disk to find the ID of the drive (by looking at the Size of the disks) and then I use select disk to set the focus to that drive.  Note that the results include the arrowed lines “Current Read-only State : Yes” and “Read-only : No”:


I had seen examples online where both attributes were set to “Yes” and the recommended fix was to try the command attrib disk clear readonly.  I tried it anyway but it made no difference, with the attributes appearing the same afterwards:


There were also references online on this subject to registry key HKEY_LOCAL_Machine\System\CurrentControlSet\Control\StorageDevicePolicies having a DWORD value WriteProtect that needed changing from 1 to 0.  I didn’t have this key or value on my system.  I then suspected this was almost certainly a hardware failure of some sort and then confirmed the drive did not work on a different computer.

More Googleage revealed what had happened.  It appears to be a deliberate feature in the drive firmware that when it detects that the drive is having problems, it becomes permanently write-protected to protect the data on there from further loss.

I contacted Kingston and the end result is that the drive is being replaced under warranty.  I would like to add that this is the second dealing I’ve had with Kingston’s technical support (a different reason previously) and I have found them outstanding both times!




When a user logs onto a domain PC, the authenticating domain controller updates a non-replicated attribute of the user account called lastLogon in its copy of the domain partition.  There is another attribute called lastLogonTimeStamp (since Server 2003) that is replicated but it is not updated on every single logon.  To reduce replication traffic, it is only updated when the value is (by default) 9 to 14 days out of date.  This attribute is designed for assisting detecting stale accounts, not getting a definitive date.  More info is here.

Sometimes though, it can be useful to know exactly when a user last logged on.  Here’s a script I wrote today that queries all domain controllers and gets the lastLogon attribute from all of them to find which is the newest and thus actual Last Logon.  The attribute is stored in UTC format and so returned as an Int64.  Interestingly, PowerShell provides a helpful extra property that contains a DateTime translated version of lastLogonTimeStamp called lastLogonDate.  My script has to do the translation of the lastLogon attribute’s format itself.  See the notes after the script.

function Get-LastLogonDateTime {
#requires -Version 3.0 -Modules ActiveDirectory
    param (
        [Parameter(Mandatory, ValueFromPipeline, HelpMessage='Enter one or more usernames separated by commas.')]

    BEGIN {
        $DCs = Get-ADDomainController -Filter '*'

        foreach ($user in $Username) {
            Write-Verbose ('Processing user "{0}"...' -f $user)
            try {
                Get-ADUser -Identity $user | Out-Null
            } catch {
                Write-Error ('User "{0}" does not exist.' -f $user)
            [Int64]$lastLogon = 0
            foreach ($DC in $DCs) {
                $domainController = $DC.HostName
                Write-Verbose ('Querying Domain Controller "{0}"...' -f $domainController)
                $dcLastLogon = Get-ADUser -Identity $user -Server $domainController -Properties lastLogon | Select-Object -ExpandProperty lastLogon
                $lastLogon = [Math]::Max($lastLogon, $dcLastLogon)
            $lastLogonDateTime = [DateTime]::FromFileTime($lastLogon)
            $obj = [pscustomobject]@{
                'Username' = $user
                'LastLogonDateTime' = $lastLogonDateTime
            Write-Output $obj

    END {}

When looping through each domain controller in turn, I need to compare the returned lastLogon attribute with what has already been found and just keep track of the newest value.  Since its an integer, I merely need to keep the greatest one.  The easiest way to do this is to use the Max( xy ) static method of .NET’s [Math] class which returns the biggest of two numbers.  I pass it the value from the currently-queried domain controller and the previous biggest value seen.

$lastLogon = [Math]::Max($lastLogon, $dcLastLogon)

On the first time through the loop, the value being compared with is set to 0 but note I had to strongly type the variable holding it as an Int64.

[Int64]$lastLogon = 0

This is because the lastLogon attribute is an Int64 and the Math.Max() method expects the two numbers being compared to be of the same type.  If I’d initialised that $lastLogon variable without strongly typing it, it would have been an Int32 by default, which would make the method call fail.  Yes, I found this out the hard way!

Once the newest value is obtained, the script then converts it to a normal [DateTime] value by using a static method on the [DateTime] class.

$lastLogonDateTime = [DateTime]::FromFileTime($lastLogon)

I’ve returned the final value as an Object and written the function so it can handle multiple usernames by the parameter or from the pipeline.

I’m considering writing a meatier version 2 that will also try and get the hostname of the computer the user logged on to from the Security log of the domain controller that authenticated them…!