Good thing they disabled the “bad” functionality rather than making the signature check more robust, as looking at the screenshots in the whitepaper there’s at least two more ways of bypassing the signature check.
They get the client PID from the named pipe (“probably” copied from StackOverflow). This PID is set when the pipe client is created, it doesn’t reflect the actual PID of the last writing process. So you could open the pipe, duplicate the handle to a new process, kill the previous one and respawn a suspended signed executable until the PIDs match. Fortunately I think in this case it might have been tricky to bypass as there’s only a short window of time between the connection being made and the PID check, but in general it’d be useful.
They use Process.MainModule to read the filename. That name is read from the memory space of the target process (it’s part of the loader list managed by NTDLL) so the calling process can spoof it. The same bug exists in UAC checks of course 🙂
Also the whitepaper says the exploit needed a self signed file, which works because the checks the code does isn’t very thorough. But it turns out you don’t even need to install a fake root cert. The code uses X509Certificate.CreateFromSignedFile which does not verify the PE signature, it just reads out the certificate from the PE file. So you can just take the certificate info section from a Checkpoint signed file and insert that into your arbitrary binary file. The hash won’t match, anything using WinVerifyTrust would spot the fake but in this case the certificate they get back is exactly what the code expects, Verify() would check it’s valid against the real root cert. Matt Graeber did a write up of doing this trick, and I exploited almost the exact same bug class in McAfee TrueKey 🙂