GottaFix for WannaCrypt?

110

16

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!

Notts90 supports Monica

Posted 2017-05-16T08:58:03.947

Reputation: 1 211

3Hmm, 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? – Kevin Cruijssen – 2017-05-16T09:14:08.183

@KevinCruijssen even if it was, your answer fails the "only one truthy value" ;-) – John Dvorak – 2017-05-16T09:18:10.723

I don't think it's listed in the "allowed IO methods" meta-question, but feel to add it there to see if it gains traction. – John Dvorak – 2017-05-16T09:19:22.330

3@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. – Notts90 supports Monica – 2017-05-16T09:20:17.277

Nice. My suggestion to list this in the general IO rules still applies, though. – John Dvorak – 2017-05-16T09:26:46.870

12If users missed this patch but installed a later one they will still be protected so this could give a false negative for some users. – Ian Miller – 2017-05-16T11:46:44.810

1I'd be interested in seeing some answers that actually test for the presence of the vulnerability rather than the presence of the patch. I'm not sure how easy it is to exploit/trigger and if it could be done in a short code snippet. – Micheal Johnson – 2017-05-16T20:52:57.170

2@MichealJohnson not sure it's wise to encourage people to post code demonstrating how to exploit the vulnerability. – Notts90 supports Monica – 2017-05-16T20:57:04.030

8Is the infection of the host pc a valid falsey value? It would obviously get the point across – Nic Robertson – 2017-05-16T22:13:15.623

1I thought this was going to be a question AboutJoining WordsTogether LikeThis. – Esolanging Fruit – 2017-05-17T02:38:54.560

Can we use the vulnerability to show the answer ? – Hybris95 – 2017-05-19T13:57:55.420

@Hybris95 No, the challenge is to test if the specific patch is installed, the vulnerability could have been fixed in a different patch. – Notts90 supports Monica – 2017-05-19T14:02:09.837

@IanMiller I'd not use some codegolf thingy to do serious stuff in real life... – Erik the Outgolfer – 2017-08-15T14:13:05.640

Answers

159

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

Kevin Cruijssen

Posted 2017-05-16T08:58:03.947

Reputation: 67 575

83an answer on PPCG that's actually useful for practical purposes? I'm impressed. – John Dvorak – 2017-05-16T09:10:57.393

1You 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. – whatever – 2017-05-16T09:15:11.860

1@JanDvorak see comment on question, happy to allow an error as a false value as I think it's a clear indicator the patch isn't installed. – Notts90 supports Monica – 2017-05-16T09:22:34.513

this command just froze my powershell :( – LLlAMnYP – 2017-05-16T09:47:43.983

@lllamnyp are you sure it really froze permanently? It can take quite some time... – whatever – 2017-05-16T10:52:38.350

On Win10 it fails (obviously) in ~ 3 seconds – CalvT – 2017-05-16T10:57:59.357

6Doesn't work if you are already on the next or later monthly roll-up, because those replace each other. – Sumyrda - Reinstate Monica – 2017-05-16T12:01:10.447

@Sumyrda the challenge is to check for this specific patch, it doesn't have to check for replacement patches. – Notts90 supports Monica – 2017-05-16T12:08:24.717

6@Notts90 Yes, the comment is meant as a hint for people who try the code and get a false negative. – Sumyrda - Reinstate Monica – 2017-05-16T12:55:36.003

10Just hotfix KB4012212 is enough. In Powershell you don't need to write get-. – Danko Durbić – 2017-05-16T13:11:53.193

1@DankoDurbić, you have to if there happens to be another command matching the command without Get-, but in this particular case it works :-) – Joey – 2017-05-18T19:17:58.460

does anyone know if this works for Petya too? – Isaac – 2017-06-27T21:51:38.277

43

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

Kevin Cruijssen

Posted 2017-05-16T08:58:03.947

Reputation: 67 575

5this will get problematic once 40M updates rolls around – John Dvorak – 2017-05-16T10:14:55.073

1use find instead of findstr, it saves 3 bytes – stevefestl – 2017-05-16T10:17:27.190

2Doesn't work if you are already on the next or later monthly roll-up, because those replace each other. – Sumyrda - Reinstate Monica – 2017-05-16T12:02:48.387

2@Sumyrda the challenge is to check for this specific patch, it doesn't have to check for replacement patches. – Notts90 supports Monica – 2017-05-16T12:08:43.923

1find "4012212" also works for -1 byte, wmic qfe|find "4012212" seems to work too but maybe i'm missing something there? – Bassdrop Cumberwubwubwub – 2017-05-16T14:58:40.100

20

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.

Captain Man

Posted 2017-05-16T08:58:03.947

Reputation: 386

1Oh well yeah that's shorter than mine ; I didn't pick the good MS user to steal from ! – Aaron – 2017-05-16T15:38:52.680

2Someone edited this to include "Or WSL" which I guess is true but you'd have to modify the path first. – Captain Man – 2017-05-17T12:55:50.037

17

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.

Ryan

Posted 2017-05-16T08:58:03.947

Reputation: 171

13Hi, 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) – Kevin Cruijssen – 2017-05-16T15:01:19.590

2Oh, 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. :) – Kevin Cruijssen – 2017-05-18T08:05:10.117

2Can'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 – pinkfloydx33 – 2017-05-21T09:28:15.517

16

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;

TheLethalCoder

Posted 2017-05-16T08:58:03.947

Reputation: 6 930

isn't if(h["HotFixID"]=="KB4012212")return 1>0;return 1<0; the same as return h["HotFixID"]=="KB4012212"? – Julian Wolf – 2017-05-16T15:05:46.507

@JulianWolf No because the latter would only check the first item that comes back whereas the former checks on each iteration. – TheLethalCoder – 2017-05-16T15:07:20.697

Ah, right. I miscounted parentheses and though the foreach had ended. – Julian Wolf – 2017-05-16T15:08:32.063

Why not return 1 or 0, not true or false? – programmer5000 – 2017-05-16T15:27:29.453

@programmer5000 The only truthy/falsey values in C# are bools. – TheLethalCoder – 2017-05-16T15:28:13.750

1Could 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 – Ryan – 2017-05-18T09:50:46.743

@Ryan Turns out you can, don't know why I didn't think of that haha. Also means I can now use an implicit return to save even more bytes. – TheLethalCoder – 2017-05-18T10:00:49.120

5+1 For not being in a shell scripting language. – Hjulle – 2017-05-18T15:07:32.367

Could replace .Get().Count>0 with .Get().Any()? – aloisdg moving to codidact.com – 2017-05-19T14:50:24.303

@aloisdg Only with the penalty of adding using System.Linq; to the byte count. – TheLethalCoder – 2017-05-19T14:51:27.763

@TheLethalCoder I dont count it since some C# script env include it by default. I dont know if we have a rule for that. – aloisdg moving to codidact.com – 2017-05-19T14:54:05.900

@aloisdg If it needs it to run, it should be included and this is a "normal" C# program so it needs it. That said C# interactive and possibly some other things, like Linqpad?, include it by default without you knowing they're included so you don't need to add it into the byte count for those. – TheLethalCoder – 2017-05-19T14:58:09.027

I'm not sure, but since the SELECT statements looks like a regular SQL-query to me, can't you remove the spaces at WHERE HotFixID='KB3150513' for -2 bytes? – Kevin Cruijssen – 2017-05-21T12:48:56.273

@KevinCruijssen Sure can! – TheLethalCoder – 2017-05-21T12:56:58.697

2Erik Karlsson (who doesn't have enough rep to comment) suggested in an edit to save 7 bytes by replacing SELECT HotFixID with SELECT *. – Martin Ender – 2017-05-22T11:29:42.210

14

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

Aaron

Posted 2017-05-16T08:58:03.947

Reputation: 3 689

Will this work if you remove the KB? – TheLethalCoder – 2017-05-16T15:39:30.203

@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

– Aaron – 2017-05-16T15:40:57.413

Fair enough I didn't know enough about what yours was doing hence the question not a suggestion :) – TheLethalCoder – 2017-05-16T15:43:19.717

3This 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. – Sirens – 2017-05-17T00:31:57.370

4@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 – Aaron – 2017-05-17T09:58:56.153

Wouldn't this also report yes on a failed install? – Felix Dombek – 2017-05-19T08:46:49.417

@FelixDombek I've checked my log and did not found any error on package installation that would mention their name (although I found a few errors while retrieving updates or testing applicability). I wouldn't be surprised if you were right, but I don't know how to reproduce an error that would (dis?)prove it – Aaron – 2017-05-19T08:57:11.797

12

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)

MKPhil

Posted 2017-05-16T08:58:03.947

Reputation: 121

3Welcome to the site! Nice first answer! – programmer5000 – 2017-05-19T13:14:02.943

7

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 :)

George

Posted 2017-05-16T08:58:03.947

Reputation: 1 355

1I think you can remove the spaces around the pipe: systeminfo|find "4012212" for -2 bytes. – Kevin Cruijssen – 2017-05-21T12:52:13.947

5

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

MarkPippin

Posted 2017-05-16T08:58:03.947

Reputation: 51

I'm not sure, but I think you can change (Get-HotFix | where to (HotFix|where (spaces removed, and Get- removed. – Kevin Cruijssen – 2017-05-18T08:08:23.223

3

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

Luke

Posted 2017-05-16T08:58:03.947

Reputation: 31

1You can remove the spaces around the pipe: (HotFix|? HotFixID ... for -2 bytes. – Kevin Cruijssen – 2017-05-21T12:53:22.187

2

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

Kevin Cruijssen

Posted 2017-05-16T08:58:03.947

Reputation: 67 575