How to whitelist your AutoRuns artifacts

Have you ever wondered how can I create a whitelist of my known harmless AutoRuns artifacts?

There are various ways to filter and ignore known artifacts. It can be done either for hunting purposes and to spot more quickly what’s unknown that requires a review and (probably) further actions.

You can filter Autoruns artifacts by using the authenticode certificate, the SHA256 hash,…

All these methods will work but there are some known artifacts that are still difficult to filter out.

I’ll show here a way to deal with these artifacts and create a baseline or whitelist of known artifacts.

I’ve introduced a new function in the module to create a whitelist of artifacts stored in a .ps1 file.

You can directly send the output of the main Get-PSAutorun function to the new New-AutoRunsBaseLine so that a .ps1 file is created. This powershell script stores an array of artifcats stored as PSCustomobject.

You may wonder why a .ps1 file and not a json file. The reason is that you can use a code signing certificate to sign the created ps1 file using the built-in Set-AuthenticodeSignature cmdlet. It brings integrity. It’s a signed whitelist. Signing may also be required if you use the PowerShell constrained language mode.

You can for example store all the artifacts with the maximum properties available.

Get-PSAutorun -VerifyDigitalSignature -ShowFileHash|
New-AutoRunsBaseLine -Verbose

Later on, to see if there are any changes, you can use the second function I’ve introduced: Compare-AutoRunsBaseLine

Here’s an example where I duplicated an existing file and modified one of its properties: the ending digit of the version.

For hunting purposes, you may want to store a minimalist whitelist and use it as a filter to view what’s relevant.

Get-PSAutorun -VerifyDigitalSignature|
Where { -not($_.isOSbinary)}|
New-AutoRunsBaseLine

If you want to view what has been exported in the whitelist, you just need to run the script created.

~\Documents\PSAutoRunsBaseLine-20201102214715.ps1 |
Out-GridView -PassThru

Here’s an example where I selected only one difficult artifact to filter out from the grid output:

Here’s another example I use on my personal computer:

Get-PSAutorun -VerifyDigitalSignature -ShowFileHash |
Where {-not($_.Version)} | Where { -not($_.isOSbinary)} |
New-AutoRunsBaseLine -Verbose

If you want to see what that file contains, I’ve uploaded a version here.

If you think that these new functions are useful, please vote for them 😀

The above new functions are currently only part of the experimental branch of Autoruns repository on Github. It’s not signed digitally and the Autoruns.cat file has not been modified to reflect the changes of the main Autoruns files (.psd1 and psm1). It’s also not been published yet to the PowerShell Gallery. It all depends on your votes 😀 . If you think it’s useful, please let me know. If you think, it’s not, please let also me know. If you find issues with the code, please introduce it directly on Github using this link.

Enjoy and happy hunting 😎

Speeding up the Windows 7 installation with slipstreaming

At work, one of our hardware supplier was supposed to ship the exact same model we bought last year but they actually delivered a serie of laptops with M2 SATA based SSD disk. What a surprise!

We discovered that our immutable architecture approach was broken by this internal recent hardware component. M2 SATA and NVMe didn’t exist when Windows 7 SP1 was released in 2009.
An engineer provided two links to the following knowledge base articles:

The first link is very interesting because it exposes a way to slipstream (you may remember the Update rollup 1 for Windows XP released in 2003) hotfixes directly into the Windows 7 ISO image.
Now that Windows 7 shifted to the same “servicing” model as Window 10 (see Simplified servicing for Windows 7 and Windows 8.1: the latest improvements), it’s also a huge opportunity to reduce the number of updates required for a vanilla Windows 7 SP1 ISO image.

First, please don’t strictly follow what’s written in KB2990941, you may have some difficulties to get the Windows 8.1 ADK that was relevant and current when they released this article in September 2015. This version of ADK isn’t strictly required. Your brave old Windows 7 WAIK can do all the steps.
I’ll show below the steps using a combination of The Windows® Automated Installation Kit (AIK) for Windows® 7 + The Windows® Automated Installation Kit (AIK) Supplement for Windows® 7 SP1.

There’s a 2nd reason why you should not strictly follow what’s written.
There are two errors in the various dism commands in step 9.
The compression mentioned in the notes can only work for an online image and cannot be used for an offline image which is what we work with in method 1.

Do you have the Windows 7 WAIK installed in its default location?

What do I need?

  • You need to create folders mentioned in step 2
    md c:\temp\src
    md c:\temp\mount
    md c:\temp\winremount
    md c:\temp\hotfix
    md c:\temp\drivers
    
  • You need to copy the content of your Windows 7 ISO file to c:\temp\src
  • You need the following .cab files of the following updates placed in c:\temp\hotfix:
  • You need the following little script I wrote:
    @echo off
    :: Calculate the current directory (containing this file).
    set _WHEREAMI=%~d0%~p0
    set _WHEREAMI=%_WHEREAMI:"=%
    if not exist c:\temp\hotfix\*%1*.cab echo c:\temp\hotfix\*%1*.cab not found & goto finish
    for /f %%z in ('dir c:\temp\hotfix\*%1*.cab /S/A/B') do @ set _HotFx=%%z
    echo -Dealing with %_HotFx%-
    set _WAIKLOCATION=%programfiles%\Windows AIK
    if "%PROCESSOR_ARCHITECTURE%"=="x86" set Path=%_WAIKLOCATION%\Tools\PETools;%_WAIKLOCATION%\Tools\x86;%_WAIKLOCATION%\Tools\x86\Servicing;%PATH%
    if "%PROCESSOR_ARCHITECTURE%"=="AMD64" set Path=%_WAIKLOCATION%\Tools\PETools;%_WAIKLOCATION%\Tools\AMD64;%_WAIKLOCATION%\Tools\x86;%_WAIKLOCATION%\Tools\AMD64\Servicing;%_WAIKLOCATION%\Tools\x86\Servicing;%PATH%
    :: boot.wim index:1
    "%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Mount-WIM /WimFile:c:\temp\src\sources\boot.wim /Index:1 /MountDir:c:\temp\mount
    if not "%errorlevel%"=="0" echo Error %errorlevel% & goto error
    "%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Image:C:\temp\mount /Add-Package /PackagePath:%_HotFx%
    if not "%errorlevel%"=="0" echo Error %errorlevel% & goto error
    "%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /unmount-Wim /MountDir:"C:\temp\mount" /Commit
    if not "%errorlevel%"=="0" echo Error %errorlevel% & goto error
    :: boot.wim index:2
    "%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Mount-WIM /WimFile:c:\temp\src\sources\boot.wim /Index:2 /MountDir:c:\temp\mount
    if not "%errorlevel%"=="0" echo Error %errorlevel% & goto error
    "%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Image:C:\temp\mount /Add-Package /PackagePath:%_HotFx%
    if not "%errorlevel%"=="0" echo Error %errorlevel% & goto error
    robocopy C:\temp\mount\sources c:\temp\src\sources /r:0 /Z /XO /XF background.bmp
    "%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /unmount-Wim /MountDir:"C:\temp\mount" /Commit
    if not "%errorlevel%"=="0" echo Error %errorlevel% & goto error
    :: install.wim index:1 and winre.wim
    "%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Mount-WIM /WimFile:c:\temp\src\sources\install.wim /Index:1 /MountDir:c:\temp\mount
    if not "%errorlevel%"=="0" echo Error %errorlevel% & goto error
    "%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Image:C:\temp\mount /Add-Package /PackagePath:%_HotFx%
    if not "%errorlevel%"=="0" echo Error %errorlevel% & goto error
    "%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Mount-WIM /WimFile:c:\temp\mount\windows\system32\recovery\winre.wim /Index:1 /MountDir:c:\temp\winremount
    if not "%errorlevel%"=="0" echo Error %errorlevel% & goto error
    "%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Image:c:\temp\winremount /Add-Package /PackagePath:%_HotFx%
    if not "%errorlevel%"=="0" echo Error %errorlevel% & goto error
    "%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /unmount-Wim /MountDir:"c:\temp\winremount" /Commit
    if not "%errorlevel%"=="0" echo Error %errorlevel% & goto error
    "%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /unmount-Wim /MountDir:"C:\temp\mount" /Commit
    if not "%errorlevel%"=="0" echo Error %errorlevel% & goto error
    goto finish
    :error
    echo aborting...
    :finish
    view raw inject.bat hosted with ❤ by GitHub
  • Place the extracted version of the M2 driver provided by your favorite hardware supplier in the C:\temp\drivers

What’s next? What’s the plan?

  • We inject first the servicing stack from April 2015 that is a requirement for the convenience update
  • We inject the convenience update right after
  • Then we only inject the July 2016 rollup into the install.wim because it contains the latest version of the Window Update Agent (WUA)
  • We inject the two M2 hotfixes
  • Finally we inject the drivers

With the little script I provided, the steps are less cumbersome and error prone.
They look like this:

.\inject.bat 3020369
.\inject.bat 3125574

:: inject only July 2016 rollup (contains latest WUA) into install.wim and not boot.wim and winre.wim
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Mount-WIM /WimFile:c:\temp\src\sources\install.wim /Index:1 /MountDir:c:\temp\mount
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Image:C:\temp\mount /Add-Package /PackagePath:c:\temp\hotfix\Windows6.1-KB3172605-x64.cab
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /unmount-Wim /MountDir:"C:\temp\mount" /Commit

.\inject.bat 2990941
.\inject.bat 3087873

:: add the drivers
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Mount-WIM /WimFile:c:\temp\src\sources\boot.wim /Index:1 /MountDir:c:\temp\mount
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Image:C:\temp\mount /Add-Driver /Driver:c:\temp\drivers /Recurse
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /unmount-Wim /MountDir:"C:\temp\mount" /Commit
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Mount-WIM /WimFile:c:\temp\src\sources\boot.wim /Index:2 /MountDir:c:\temp\mount
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Image:C:\temp\mount /Add-Driver /Driver:c:\temp\drivers /Recurse
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /unmount-Wim /MountDir:"C:\temp\mount" /Commit

"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Mount-WIM /WimFile:c:\temp\src\sources\install.wim /Index:1 /MountDir:c:\temp\mount
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Image:C:\temp\mount /Add-Driver /Driver:c:\temp\drivers /Recurse
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Mount-WIM /WimFile:c:\temp\mount\windows\system32\recovery\winre.wim /Index:1 /MountDir:c:\temp\winremount
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Image:c:\temp\winremount /Add-Driver /Driver:c:\temp\drivers /Recurse
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /unmount-Wim /MountDir:"c:\temp\winremount" /Commit
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /unmount-Wim /MountDir:"C:\temp\mount" /Commit

Conclusion

Congratulations, you’ve successfully slipsteamed updates into a Windows 7 image 😀

What’s else did you get?

Well, you’ve a larger image… that’s a fact and definitely a drawback.

You also have an image that requires less post-installation updates and that can immediately, rapidly and successfully scan for missing updates against Windows Update.
That makes two benefits

In my work environment, the above slipstreamed image allowed me to divide by at least 3 the time it takes to install from scratch a fully up-to-date Windows 7 box 😎

My immutable architecture approach is repaired and performs faster like it did in 2009 when Windows 7 SP1 was RTM.

ETW provider security – fix event id 30

In february 2016, Robin ten Berge posted the following on the PM.org mailing list



The whole thread is archived here

I’ve also encountered this behavior (2 events) after rebooting and having patched 2012 R2 Hyper-V servers.
The event logging service encountered an error (5) while enabling publisher {0bf2fb94-7b60-4b4d-9766-e82f658df540} to channel Microsoft-Windows-Kernel-ShimEngine/Operational. This does not affect channel operation, but does affect the ability of the publisher to raise events to the channel. One common reason for this error is that the Provider is using ETW Provider Security and has not granted enable permissions to the Event Log service identity.

I was also able to reproduce the error by just enabling and disabling the Microsoft-Windows-Kernel-ShimEngine/Operational log when the server is running 🙂

To fix it, my google fu found this http://www.geoffchappell.com/studies/windows/win32/services/scm/events/diagnostic.htm and I just added the LOCAL SERVICE as suggested.

Here are the steps I used to fix it:

  • Launch an elevated perfmon: C:\windows\system32\perfmon.exe
  • Expand ‘Data Collector Sets’
  • Expand ‘Event Trace Sessions’
  • Right-click ‘Eventlog-System’ running session and click ‘Properties’
  • In the ‘Trace providers’ list, scroll down to ‘Microsoft-Windows-Kernel-ShimEngine’ and select it.
  • Click on the ‘Security’ button next to it
  • Click ‘Add’, type ‘LOCAL SERVICE’, click ‘Check Names’ (adjust the location if required)
  • Untick all permissions and just leave TRACELOG_GUID_ENABLE
  • Just click “Apply” button in the ‘Security settings for this ETW trace provider’
  • You don’t need to click “Apply” or “Ok” button in the parent (Eventlog-System properties( window or you’ll get an ‘Access Denied’ (normal, you are not allowed to modify a running trace)

Game plan for high performing team

I’ve borrowed both the title of this post and the following picture from Don Carew, Eunice Parisi-Carew and Ken Blanchard to illustrate what your team will go through for each event of the Winter Scripting Games.

Note: I’ll use italics whenever I quote the above authors or someone else.
(TDS = Team Development Stage)

There are two key variables. Productivity is the team’s ability to work together and achieve results. Morale is the team’s motivation, confidence and cohesion.

After each team member read the whole event description (including the criteria used by the judges for scoring), you and your team should immediately go through the first stage (TDS1) called orientation where productivity is low (you didn’t write any code yet) and morale is moderately high. Team members are moderately eager and have high expectations. They need direction and have some anxiety about their roles and their connections with the team.

To go through phase 1, you and your team will need to adopt a structuring approach. I think that you’ll need to:

  1. Identify the main goal of the event
  2. For the practice event, the main goal could be: inventory servers by scanning an IPv4 subnet, gather data like the CPU, RAM,…installed components and save data to files in a reusable format.

  3. Identify skills among your team
  4. Some team members may be more familiar than others about the network part. They should know what a CIDR is. Some may be more familiar with WMI,…

  5. Divide to conquer
  6. You should split each problem into tasks and create one function to achieve one task. Each function should do one single thing and do it well.

  7. Clarify roles
  8. Make sure that each member in your team has had a role assigned, i.e. is responsible for writing the function that does this…

Now each team member starts his journey and writes some code 😀 …

… and your team is actually slowly moving toward phase 2 (TDS2) called dissatisfaction.

Productivity is low to some. Skills and knowledge are slowly developping. Some results are occuring. Morale is low. There is a discrepency between expectations and reality. Team members have feelings of anger, frustration, confusion and discouragement.

This is in my opinion the most difficult phase to overcome.
As soon as you feel that morale is at its lowest point, it means that you matured enough to share your code on the scripting games site and get the help of coaches.

Coaches will do their best to provide high quality support and direction to your team. Resolving is the keyword for this phase. But don’t get me wrong. Some conflicts may arise among your team. You’re on your own to solve these conflicts. My last advice about this situation is that you’ve to listen and you can also use a tool like the “ladder of inference to avoid jumping to conclusions”. The following article provides some tips that may help you.