109
\$\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\$
  • 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\$ – Kevin Cruijssen May 16 '17 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 May 16 '17 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 May 16 '17 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 May 16 '17 at 20:57
  • 7
    \$\begingroup\$ Is the infection of the host pc a valid falsey value? It would obviously get the point across \$\endgroup\$ – Nic Robertson May 16 '17 at 22:13

11 Answers 11

159
\$\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\$
  • 83
    \$\begingroup\$ an answer on PPCG that's actually useful for practical purposes? I'm impressed. \$\endgroup\$ – John Dvorak May 16 '17 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 May 16 '17 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\$ – Sumyrda - Reinstate Monica May 16 '17 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\$ – Sumyrda - Reinstate Monica May 16 '17 at 12:55
  • 10
    \$\begingroup\$ Just hotfix KB4012212 is enough. In Powershell you don't need to write get-. \$\endgroup\$ – Danko Durbić May 16 '17 at 13:11
43
\$\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
    \$\begingroup\$ this will get problematic once 40M updates rolls around \$\endgroup\$ – John Dvorak May 16 '17 at 10:14
  • 1
    \$\begingroup\$ use find instead of findstr, it saves 3 bytes \$\endgroup\$ – stevefestl May 16 '17 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\$ – Sumyrda - Reinstate Monica May 16 '17 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 May 16 '17 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\$ – Bassdrop Cumberwubwubwub May 16 '17 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\$
  • 1
    \$\begingroup\$ Oh well yeah that's shorter than mine ; I didn't pick the good MS user to steal from ! \$\endgroup\$ – Aaron May 16 '17 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\$ – Captain Man May 17 '17 at 12:55
17
\$\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\$
  • 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\$ – Kevin Cruijssen May 16 '17 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\$ – Kevin Cruijssen May 18 '17 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\$ – pinkfloydx33 May 21 '17 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\$
  • \$\begingroup\$ isn't if(h["HotFixID"]=="KB4012212")return 1>0;return 1<0; the same as return h["HotFixID"]=="KB4012212"? \$\endgroup\$ – Julian Wolf May 16 '17 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\$ – TheLethalCoder May 16 '17 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 May 18 '17 at 9:50
  • 5
    \$\begingroup\$ +1 For not being in a shell scripting language. \$\endgroup\$ – Hjulle May 18 '17 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\$ – Martin Ender May 22 '17 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\$
  • \$\begingroup\$ Will this work if you remove the KB? \$\endgroup\$ – TheLethalCoder May 16 '17 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 May 16 '17 at 15:40
  • \$\begingroup\$ Fair enough I didn't know enough about what yours was doing hence the question not a suggestion :) \$\endgroup\$ – TheLethalCoder May 16 '17 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\$ – Sirens May 17 '17 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 May 17 '17 at 9:58
12
\$\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\$
  • 3
    \$\begingroup\$ Welcome to the site! Nice first answer! \$\endgroup\$ – programmer5000 May 19 '17 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
    \$\begingroup\$ I think you can remove the spaces around the pipe: systeminfo|find "4012212" for -2 bytes. \$\endgroup\$ – Kevin Cruijssen May 21 '17 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\$
  • \$\begingroup\$ I'm not sure, but I think you can change (Get-HotFix | where to (HotFix|where (spaces removed, and Get- removed. \$\endgroup\$ – Kevin Cruijssen May 18 '17 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
    \$\begingroup\$ You can remove the spaces around the pipe: (HotFix|? HotFixID ... for -2 bytes. \$\endgroup\$ – Kevin Cruijssen May 21 '17 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, privacy policy and cookie policy

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