113
\$\begingroup\$

Warning

The answers to this challenge test for a specific version of the patch that helps stop WannaCrypt/WannaCry attacks. Depending on your operating system, you may have a different patch. The best way to protect yourself is to make sure your PC is fully up to date and be careful when opening attachments and web links.


Introduction

I like to think programmers are inherently good people, even if some aren't so nice, so lets help people make sure they are protected with the MS17-010 patch.

Challenge

Your challenge is to write a full program or function that returns a truthy or falsey value depending on if the MS17-010 patch is installed on the current operating system.

Input and Output

Input: No input required

Output: A truthy or falsey value (Indicate which is used for each case). An error/exception can be considered a falsey value.

Rules

  • Your code should run (and output correctly) on at least one windows operating system for which the patch is available, but doesn't have to run on every operating system (Please state any limitations).
  • Standard loopholes apply
  • This is , so the submission with the least amount of bytes wins!
\$\endgroup\$
13
  • 3
    \$\begingroup\$ Hmm, one question.. Regarding the truthy/falsey values, is an error allowed as falsey value, and truthy as an actual return, or isn't this allowed? \$\endgroup\$ Commented May 16, 2017 at 9:14
  • 3
    \$\begingroup\$ @KevinCruijssen I'm happy to consider an error as a falsely value. I think it's a clear indicator that the patch is not installed. \$\endgroup\$
    – Notts90
    Commented May 16, 2017 at 9:20
  • 12
    \$\begingroup\$ If users missed this patch but installed a later one they will still be protected so this could give a false negative for some users. \$\endgroup\$
    – Ian Miller
    Commented May 16, 2017 at 11:46
  • 2
    \$\begingroup\$ @MichealJohnson not sure it's wise to encourage people to post code demonstrating how to exploit the vulnerability. \$\endgroup\$
    – Notts90
    Commented May 16, 2017 at 20:57
  • 8
    \$\begingroup\$ Is the infection of the host pc a valid falsey value? It would obviously get the point across \$\endgroup\$ Commented May 16, 2017 at 22:13

11 Answers 11

158
\$\begingroup\$

PowerShell 2.0, 24 20 16 bytes

hotfix KB4012212

-4 bytes thanks to @whatever by removing -id.
-4 bytes thanks to @DankoDurbić by changing get-hotfix to hotfix.

KB4012212 is the patch for Windows 7. This can be replaced with any KB-code from the linked page of the patch.

Will return the Source, Description, HotFixID, InstalledBy and InstalledOn information when it's installed as truthy value, and will give an error if it's unable to find it as falsey value.

Here is an example of both a truthy and falsey output (so KB4012212 is installed on my machine, but KB4012215 is not):

enter image description here

\$\endgroup\$
12
  • 86
    \$\begingroup\$ an answer on PPCG that's actually useful for practical purposes? I'm impressed. \$\endgroup\$ Commented May 16, 2017 at 9:10
  • 1
    \$\begingroup\$ You don't need to specify the id Get-HotFix KB4012212 will work too. (Tested with PSv4 only). But I agree with Jan Dvorak, I don't think the output confirms to the challenge. \$\endgroup\$
    – whatever
    Commented May 16, 2017 at 9:15
  • 6
    \$\begingroup\$ Doesn't work if you are already on the next or later monthly roll-up, because those replace each other. \$\endgroup\$ Commented May 16, 2017 at 12:01
  • 6
    \$\begingroup\$ @Notts90 Yes, the comment is meant as a hint for people who try the code and get a false negative. \$\endgroup\$ Commented May 16, 2017 at 12:55
  • 10
    \$\begingroup\$ Just hotfix KB4012212 is enough. In Powershell you don't need to write get-. \$\endgroup\$ Commented May 16, 2017 at 13:11
42
\$\begingroup\$

Batch / Windows CMD, 31 29 28 23 bytes

wmic qfe|find "4012212"

-1 byte thanks to @SteveFest by changing findstr 4012212 to find "4012212".
-5 bytes thanks to @BassdropCumberwubwubwub by removing list.

Explanation:

wmic          Windows Management Instrumentation Command-line
qfe           Quick Fix Engineering
|find "..."   Looks for the string in the complete output

Outputs some patch info if it's installed, or nothing otherwise.
In the screenshot below, patch 4012212 is installed, and 4012215 is not.

enter image description here

\$\endgroup\$
5
  • 5
    \$\begingroup\$ this will get problematic once 40M updates rolls around \$\endgroup\$ Commented May 16, 2017 at 10:14
  • 1
    \$\begingroup\$ use find instead of findstr, it saves 3 bytes \$\endgroup\$
    – stevefestl
    Commented May 16, 2017 at 10:17
  • 2
    \$\begingroup\$ Doesn't work if you are already on the next or later monthly roll-up, because those replace each other. \$\endgroup\$ Commented May 16, 2017 at 12:02
  • 2
    \$\begingroup\$ @Sumyrda the challenge is to check for this specific patch, it doesn't have to check for replacement patches. \$\endgroup\$
    – Notts90
    Commented May 16, 2017 at 12:08
  • 1
    \$\begingroup\$ find "4012212" also works for -1 byte, wmic qfe|find "4012212" seems to work too but maybe i'm missing something there? \$\endgroup\$ Commented May 16, 2017 at 14:58
20
\$\begingroup\$

Bash + Cygwin (Or WSL), 21 bytes

This answer is mostly stolen from Kevin's answer. So throw an upvote that way also if you think this deserves one.

wmic qfe|grep 4012212

Cygwin has access to the Windows commands in addition to coreutils. We are able to use coreutils's grep instead of Windows's find so we don't need to use quotes. 2 bytes are saved because of this.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Oh well yeah that's shorter than mine ; I didn't pick the good MS user to steal from ! \$\endgroup\$
    – Aaron
    Commented May 16, 2017 at 15:38
  • 2
    \$\begingroup\$ Someone edited this to include "Or WSL" which I guess is true but you'd have to modify the path first. \$\endgroup\$ Commented May 17, 2017 at 12:55
18
\$\begingroup\$

Powershell 5.1, 245 212 207 bytes

$S=New-Object -ComObject Microsoft.Update.Session;$T=$S.CreateUpdateSearcher();$H=$‌​T.GetTotalHistoryCo‌​unt();$p=0;$T.Query‌​History(0,$H)|ForEa‌​ch-Object -Process{if($_.Title -like"*KB4013429*"){$p=1;}};echo $p;

-33 bytes thanks to @KevinCruijssen removing white space and replacing true and false with 1 and 0.

-5 bytes thanks to @KevinCruijssen shortening variable names

Obviously not going to win any prizes, but this powershell script will check the Microsoft Update history log for KB4013429 (one of the patches listed on the link) it can be replaced with any of the patches. Thought I'd post it because it's a little more reliable if the patch has been replaced with a later one.

\$\endgroup\$
3
  • 13
    \$\begingroup\$ Hi, welcome to PPCG! :) Since this question is tagged code-golf, the idea is to complete the challenge in as few bytes as possible. I know your answer probably won't win anyway, and you've used a more complete method than I did, but you can still golf your current answer by removing unnecessary whitespaces, and use 1/0 instead of of true/false. Like this: $S=New-Object -ComObject Microsoft.Update.Session;$Se=$S.CreateUpdateSearcher();$Hc=$Se.GetTotalHistoryCount();$p=0;$Se.QueryHistory(0,$Hc)|ForEach-Object -Process{if($_.Title -like"*KB4013429*"){$p=1;}};echo $p; (212 bytes) \$\endgroup\$ Commented May 16, 2017 at 15:01
  • 2
    \$\begingroup\$ Oh, and another thing you can golf which I only notice now: It's best to always use single-character variable/method/class names. So you can change the Hc to H and the Se to T (or another single letter besides H or S which you've already used) to save another 5 bytes. :) \$\endgroup\$ Commented May 18, 2017 at 8:05
  • 2
    \$\begingroup\$ Can't you pass $H directly instead of storing in? Also %{ } and ?{ } instead of ForEach-Object and if. Pretty sure you can just output to the pipeline rather than the echo since you should only have one result match and I think that would count as truthy based on the OP \$\endgroup\$ Commented May 21, 2017 at 9:28
16
\$\begingroup\$

C#, 178 143 141 134 bytes

_=>new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_QuickFixEngineering WHERE HotFixID='KB3150513'").Get().Count>0;

Compiles to a Func<int, bool> where the input is unused.

Saved 35 bytes with the help of @Ryan
Saved 2 bytes thanks to @KevinCruijssen
Saved 7 bytes thanks to @ErikKarlsson

Formatted version:

System.Func<int, bool> f = _ =>
    new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_QuickFixEngineering WHERE HotFixID = 'KB3150513'")
                         .Get().Count > 0;
\$\endgroup\$
15
  • \$\begingroup\$ isn't if(h["HotFixID"]=="KB4012212")return 1>0;return 1<0; the same as return h["HotFixID"]=="KB4012212"? \$\endgroup\$ Commented May 16, 2017 at 15:05
  • \$\begingroup\$ @JulianWolf No because the latter would only check the first item that comes back whereas the former checks on each iteration. \$\endgroup\$ Commented May 16, 2017 at 15:07
  • 1
    \$\begingroup\$ Could you add a where clause in the ManagementObjectSearcher query and add a count on the end of the .get()? Like this: _=>{if (new System.Management.ManagementObjectSearcher("SELECT HotFixID FROM Win32_QuickFixEngineering WHERE HotFixID = 'KB3150513'").Get().Count > 0)return 1>0;return 1<0;};. To save 4 bytes \$\endgroup\$
    – Ryan
    Commented May 18, 2017 at 9:50
  • 5
    \$\begingroup\$ +1 For not being in a shell scripting language. \$\endgroup\$
    – Hjulle
    Commented May 18, 2017 at 15:07
  • 2
    \$\begingroup\$ Erik Karlsson (who doesn't have enough rep to comment) suggested in an edit to save 7 bytes by replacing SELECT HotFixID with SELECT *. \$\endgroup\$ Commented May 22, 2017 at 11:29
14
\$\begingroup\$

Cygwin, 31 bytes

Just to play the rebel

grep KB4012212 "$WINDIR"/*e.log

the return code will be 0 if the patch has been applied, or 1 if it hasn't.

Tested under Windows 7 with Cygwin 2.6.0

\$\endgroup\$
7
  • \$\begingroup\$ Will this work if you remove the KB? \$\endgroup\$ Commented May 16, 2017 at 15:39
  • \$\begingroup\$ @TheLethalCoder I'm not sure, and I don't think I can find out. My answer is derived from ryan's and we both search text in the huge WindowsUpdate.log which contains much more than the KB names, I wouldn't bet the number can't appear in another context \$\endgroup\$
    – Aaron
    Commented May 16, 2017 at 15:40
  • \$\begingroup\$ Fair enough I didn't know enough about what yours was doing hence the question not a suggestion :) \$\endgroup\$ Commented May 16, 2017 at 15:43
  • 3
    \$\begingroup\$ This should work if you remove KB since it's rather unlikely that 4012212 will be there in anything except the path. You could also save 1 byte if you remove just the K because you're not going to find B4012212 randomly without the path. \$\endgroup\$
    – Allison
    Commented May 17, 2017 at 0:31
  • 4
    \$\begingroup\$ @Sirens I'm not confident about testing the number only, I would be afraid to match 1) number of bytes transferred, 2) updates, report events and jobs UIDs or 3) hex error (and others) codes. Removing only the K first seems reasonable, but then B... becomes a valid hex representation, making collision with UIDs and hex codes possible \$\endgroup\$
    – Aaron
    Commented May 17, 2017 at 9:58
11
\$\begingroup\$

PowerShell v4, 64 bytes

HotFix|? HotFixID -m "401(221[2-7])|(2598)|(2606)|(3198)|(3429)"

Checks for all KB refs using a RegEx (now you have two problems)

\$\endgroup\$
1
  • 3
    \$\begingroup\$ Welcome to the site! Nice first answer! \$\endgroup\$
    – user58826
    Commented May 19, 2017 at 13:14
7
\$\begingroup\$

Batch/Command Prompt, 27 25 bytes

systeminfo|find "4012212"

If KB4012212 is found output that, otherwise nothing is outputted.

Thanks to @Kevin for saving 2 bytes :)

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I think you can remove the spaces around the pipe: systeminfo|find "4012212" for -2 bytes. \$\endgroup\$ Commented May 21, 2017 at 12:52
5
\$\begingroup\$

Powershell 2.0, 142 bytes

  • Returns 0 for "false", not patched" < 0 for "true", patched.

Below contains all KB's from March, but needs expanded with April, May KB's as each supersedes all previous.

(Get-HotFix | where HotFixID -match "4012598","4012216","4012213","4012217","4012214","4012215","4012212","4013429","4012606","4013198").Count
\$\endgroup\$
1
  • \$\begingroup\$ I'm not sure, but I think you can change (Get-HotFix | where to (HotFix|where (spaces removed, and Get- removed. \$\endgroup\$ Commented May 18, 2017 at 8:08
3
\$\begingroup\$

Powershell 5.1 134 Bytes

Same as Mark Pippin's but changed the Get-Hotfix to Hotfix and where to ? saving 8 bytes

(HotFix | ? HotFixID -match 
 "4012598","4012216","4012213","4012217","4012214","4012215","4012212","4013429","4012606","4013198").Count

I can't get it lower in byte-count than Kevin's answer

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can remove the spaces around the pipe: (HotFix|? HotFixID ... for -2 bytes. \$\endgroup\$ Commented May 21, 2017 at 12:53
2
\$\begingroup\$

DISM, 40 bytes

dism/online /get-packages|find "4012212"

Explanation:

dism             Deployment Image Servicing and Management command-line
/online          Look at current running PC's Operating System
/get-packages    Display some basic information about all packages in the image
|find "..."      Looks for the string in the complete output

Outputs the package identity if it's installed, or nothing otherwise.
In the screenshot below, patch 4012212 is installed, and 4012215 is not.

enter image description here

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.