Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
osquery: Building Signed Windows MSI and Chocolatey packages.

Building the signed osquery.msi package:

  • First build the binaries, obvi. Pay close attention here to the Cmake invocation flags. We specify the MultiThreaded to ensure there's no requirement on a linkage of MSVCRT, and further build the tests to ensure they're mostly passing locally.
PS C:\Users\Nicholas\work\repos\osquery\build\windows10> cmake -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DOSQUERY_BUILD_TESTS=ON -G "Visual Studio 16 2019" -A x64 -T v141 ..\..\                                       -- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19041.
-- osquery version: 4.4.0
-- Build type:
-- Shared libraries: OFF
-- Importing: source/boost
-- Importing: source/bzip2
-- Importing: source/gflags
...

PS C:\Users\Nicholas\work\repos\osquery\build\windows10> cmake --build . --config Release -j24 

...


PS C:\Users\Nicholas\work\repos\osquery\build\windows10> cmake --build . --config Release -j24 --target run_tests

...
  • Next up, for the MSI, we can sign the binaries:
# "Dot source" the `osquery_utils.ps1` script:
PS C:\Users\Nicholas\work\repos\osquery> . .\tools\deployment\chocolatey\tools\osquery_utils.ps1

# I use a helper function for setting the authenticode signature:
PS C:\Users\Nicholas\work\repos\osquery\build\windows10> function Set-AuthenticodeSignature() {
  param(
    [string] $binpath = '',
    [string] $certpath = '',
    [string] $certpw = ''
  )

  if (-not (Get-Command 'signtool.exe' -ErrorAction SilentlyContinue)) {
    Write-Host '[-] signtool.exe was not found in system path' -ForegroundColor Red
    exit
  }
  $signtool = (Get-Command 'signtool.exe').Source

  $signtool_args = @(
    'sign',
    "/f $certpath",
    "/p `"$certpw`"",
    '/tr http://timestamp.digicert.com',
    '/td sha256',
    '/fd sha256',
    "$binpath"
  )

  $null = Start-OsqueryProcess $signtool $signtool_args $false
}

# Now you can actually sign the binaries. I have my certs on a bitlocker encrypted thumb drive:
PS C:\Users\Nicholas\work\repos\osquery\build\windows10> Set-AuthenticodeSignature 'C:\Users\Nicholas\work\repos\osquery\build\windows10\osquery\Release\osqueryd.exe' F:\Path\To\signing_cert.p12 '<CODE SIGNING CERT PW>'

PS C:\Users\Nicholas\work\repos\osquery\build\windows10> Set-AuthenticodeSignature 'C:\Users\Nicholas\work\repos\osquery\build\windows10\osquery\Release\osqueryi.exe' F:\Path\To\signing_cert.p12 '<CODE SIGNING CERT PW>'

# Next, build the MSI and sign it:
PS C:\Users\Nicholas\work\repos\osquery\build\windows10> cmake --build . --config Release -j24 --target package
Microsoft (R) Build Engine version 16.3.2+e481bbf88 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.

  Generating ../../test_configs/aws
  Generating ../test_configs/specs/darwin
  Generating .
  Generating ../../test_configs/test.config.d

...

PS C:\Users\Nicholas\work\repos\osquery\build\windows10> Set-AuthenticodeSignature 'C:\Users\Nicholas\work\repos\osquery\build\windows10\osquery-4.4.0.msi' F:\Path\To\signing_cert.p12 '<CODE SIGNING CERT PW>'

# That's it, distribute the signed MSI
# You can check your work by verifying that the MSI has a digital signature
# and further that after you install from said MSI, both the osqueryd.exe and osqueryi.exe
# binaries have digital signatures. I like to do this process both from an upgrade
# and clean install stand point.

Building and signing the osquery Chocolatey packages:

  • Run the cmake generation with the nupkg build target, again pay attention to cmake variables, and build the binaries:
PS C:\Users\Nicholas\work\repos\osquery\build\windows10> cmake -DPACKAGING_SYSTEM=NuGet -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DOSQUERY_BUILD_TESTS=ON -G "Visual Studio 16 2019" -A x64 -T v141 ..\..\
...

PS C:\Users\Nicholas\work\repos\osquery\build\windows10> cmake --build . --config Release -j24

...

  • Similar to the MSI, sign the osqueryi and osqueryd binaries, and then produce the chocolatey package with the package target of cmake:
PS C:\Users\Nicholas\work\repos\osquery\build\windows10> Set-AuthenticodeSignature 'C:\Users\Nicholas\work\repos\osquery\build\windows10\osquery\Release\osqueryd.exe' F:\Path\To\signing_cert.p12 '<CODE SIGNING CERT PW>'

PS C:\Users\Nicholas\work\repos\osquery\build\windows10> Set-AuthenticodeSignature 'C:\Users\Nicholas\work\repos\osquery\build\windows10\osquery\Release\osqueryi.exe' F:\Path\To\signing_cert.p12 '<CODE SIGNING CERT PW>'

...

PS C:\Users\Nicholas\work\repos\osquery\build\windows10> cmake --build . --config Release -j24 --target package 
...
 CPack: - package: C:/Users/Nicholas/work/repos/osquery/build/windows10/osquery.4.4.0.nupkg generated.

  • Lastly, verify the install by installing the choco package. Again I like to verify both the clean install and upgrade workflows:
PS C:\Users\Nicholas\Desktop\osquery-release-bins\osquery-4.4.0> choco install -yf --version 4.4.0 osquery -s . --params='/InstallService'
Chocolatey v0.10.15
Installing the following packages:
osquery
By installing you accept licenses for the packages.

osquery v4.4.0 (forced)
osquery package files install completed. Performing other installation steps.
C:\Program Files\osquery\log
True
osqueryd
PATH environment variable does not have C:\Program Files\osquery in it. Adding...
Environment Vars (like PATH) have changed. Close/reopen your shell to
 see the changes (or in powershell/cmd.exe just type `refreshenv`).
 ShimGen has successfully created a shim for osqueryi.exe
 ShimGen has successfully created a shim for osqueryd.exe
 The install of osquery was successful.
  Software install location not explicitly set, could be in package or
  default install location if installer.

Chocolatey installed 1/1 packages.
 See the log for details (C:\ProgramData\chocolatey\logs\chocolatey.log).
  • This should install osquery as a system service, and you should see the digital signature on both the osqueryi and osqueryd binaries, and the service should be running
PS C:\Users\Nicholas\Desktop\osquery-release-bins\osquery-4.4.0> Get-service osqueryd
Status   Name               DisplayName
------   ----               -----------
Running  osqueryd           osqueryd
@directionless
Copy link

@muffins
Copy link
Author

muffins commented Jan 21, 2021

Test plan for the newly built binaries.

Run through the following points to make sure each thing looks right before publishing/shipping:

  • Ensure that the osquery service is running:
C:> Get-Service osqueryd
  • Ensure that osquery is reporting the correct version:
C:\> & 'C:\Program Files\osquery\osqueryd\osqueryd.exe' --version
  • Ensure that the osqueryd and osqueryi binaries are both signed:
C:\> Get-AuthenticodeSignature 'C:\Program Files\osquery\osqueryd\osqueryd.exe'
...
C:\> Get-AuthenticodeSignature 'C:\Program Files\osquery\osqueryi.exe'
  • Ensure that osquery configured with a local config is logging correctly
C:\> ls 'C:\Program Files\osquery\logs'
  • Ensure that the binaries are statically linked with the MSVCRT. The below output of dumpbin.exe is what you should see on the newly built binary.
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community>dumpbin /dependents "C:\Program Files\osquery\osqueryd\osqueryd.exe"
Microsoft (R) COFF/PE Dumper Version 14.28.29336.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file C:\Program Files\osquery\osqueryd\osqueryd.exe

File Type: EXECUTABLE IMAGE

  Image has the following dependencies:

    SHLWAPI.dll
    dbghelp.dll
    KERNEL32.dll
    USER32.dll
    SHELL32.dll
    ole32.dll
    OLEAUT32.dll
    ADVAPI32.dll
    ntdll.dll
    WS2_32.dll
    IPHLPAPI.DLL
    NETAPI32.dll
    RPCRT4.dll
    VERSION.dll
    WTSAPI32.dll
    Secur32.dll
    dbgeng.dll
    bcrypt.dll
    CRYPT32.dll
    WINTRUST.dll
    SETUPAPI.dll
    USERENV.dll
    wevtapi.dll

  Summary

       73000 .data
       62000 .pdata
      35D000 .rdata
       13000 .reloc
        1000 .rsrc
      A02000 .text
  • Specifically, you should not see linkage against the following dlls:
    MSVCP140.dll
    VCRUNTIME140.dll
    api-ms-win-crt-runtime-l1-1-0.dll
    api-ms-win-crt-heap-l1-1-0.dll
    api-ms-win-crt-stdio-l1-1-0.dll
    api-ms-win-crt-string-l1-1-0.dll
    api-ms-win-crt-convert-l1-1-0.dll
    api-ms-win-crt-utility-l1-1-0.dll
    api-ms-win-crt-filesystem-l1-1-0.dll
    api-ms-win-crt-time-l1-1-0.dll
    api-ms-win-crt-math-l1-1-0.dll
    api-ms-win-crt-locale-l1-1-0.dll
    api-ms-win-crt-environment-l1-1-0.dll

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment