Blake Burkhart

EXPERTISE;LEVEL=expert:breaking things INTEREST;LEVEL=high:programming URL:https://bburky.com/ URL:https://twitter.com/bburky/ URL:https://github.com/bburky/ URL:https://flickr.com/bburky_/ URL:https://bounty.github.com/researchers/bburky URL:https://hackerone.com/bburky URL:https://bugcrowd.com/bburky EMAIL: NOTE:A creative hacker who reads entirely too many RFCs. END:VCARD

Kyverno policy bypass using Kubernetes finalizers

Discovered that in versions of Kyverno prior to 1.10.0, Kyverno does not enforce policies on resources with a deletionTimestamp, which occurs during finalization after resource deletion begins. This allows a bypass of "validate, generate, or mutate-existing policies, even in cases where the validationFailureAction field is set to Enforce."

Impact is low for most Kubernetes resources because most controllers ignore changes during finalization. However, a few built in resource kinds such as ConfigMaps, Secrets and Services may honor changes during deletion. Custom resources may also be affected.

An attacker could first maliciously add a non-existent finalizer and begin deletion of a resource, then perform a malicious update of the resource bypassing Kyverno policies.

Playlist Extension for Playnite

A Playnite extension providing a reorderable queue of games.

A simple drag'n'drop interface in .Net WPF using GongSolutions.WPF.DragDrop.

Inject Steam GameOverlayRenderer DLL with Frida

Inspired by:

Must be run during process initialization, cannot be run after the game is started.

GameOverlayRenderer will use an appid from the SteamGameId environment variable. This is injected too. GameOverlayRenderer does not support steam_appid.txt, but this script will parse the file to discover the appid.


cd the\game\directory
frida -f "game.exe" -l C:\somewhere\GameOverlayRenderer.js --no-pause

Proof of concept SECCOMP_RET_USER_NOTIF based Frida Syscall Tracer

A hacked up version of seccomp/seccomp_user_notification.c running inside Frida.

installFilter() should be called on the main thread of the application. It's not possible to install the seccomp filter from rpc.exports.init() because it runs on a Frida thread.

installFilter() sets NO_NEW_PRIVS (required if non-root), installs the seccomp filter to trigger notifications, then creates a pthread to watch for notifications. Upon notifications a callback into Frida is invoked.

When the callback fires, it won't be on the thread that invoked the syscall. I'm not actually sure how to use Frida interact with the suspended thread. Untested, but frida/frida-gum#559 may allow running code on the thread.

Buildah/Podman chroot isolation: environment value leakage to intermediate processes

When running processes using "chroot" isolation, the process being run can examine the environment variables of its immediate parent and grandparent processes (CVE-2021-3602). This isolation type is often used when running buildah in unprivileged containers, and it is often used to do so in CI/CD environments. If sensitive information is exposed to the original buildah process through its environment, that information will unintentionally be shared with child processes which it starts as part of handling RUN instructions or during buildah run. The commands that buildah is instructed to run can read that information if they choose to.

Offline Kubernetes manifest diff (does not use cluster state)

Offline kubectl diff style tool (does not use cluster state). Diff two local files containing templated manifests (e.g. kustomize or helm output).

Resources in each file are matched by api, kind, namespace and name. This is also shown in the filename fields of the diff output.


k8s-diff.py old-manifests.yaml new-manifests.yaml
kustomize build . | k8s-diff.py /tmp/old-manifests.yaml -

EPUB full text search using SQLite FTS5

Do you ever look at the huge feature set of SQLite and try to see how many things you can use at the same time?

FTS5 + fsdir + zipfile + JOIN multiple table-valued functions = EPUB full text search

Function hooking example using avr-gdb's built-in simulator and Python

A simple example using avr-gdb's built in target sim AVR simulator on a .hex file.

GDB's Python support can be used to mock functions by modifying process state and calling ret to skip their execution.

ESPHome IR→BLE Keyboard

An ESPHome custom component to receive IR codes with remote_receiver and convert them into BLE HID keystrokes. Uses a Esp32BLEKeyboard custom component and the ESP32 BLE Keyboard library.

Python WinRT Image Capture (and Focus Stacking)

Python/WinRT is a crazy thing:

The Windows Runtime Python Projection (Python/WinRT) enables Python developers to access Windows Runtime APIs directly from Python in a natural and familiar way.

Use some native WinRT APIs via Python to capture photos with variable focus. Then use align_image_stack and enblend from the Hugin panorama tools to focus stack the images.

Capture The Flag Shitty Add-On Writeup

An I²C AVR ATtiny85 CTF writeup.

I²C, AVR assembly (with IPython magic for shellcode development), flash self-programming, and blinking LEDs.

PlaidCTF 2019: A Whaley Good Joke writeup

The challenge was to fix a broken Docker tar archive, with an unknown order of layers.

A file isn't deleted from a layer unless it was already created by a previous layer, this makes it possible to solve a dependency tree of the layers (this is what most solutions to this challenge did).

However, a much simpler solution is possible: sort the docker tar layers by mtime timestamp. The files created in the docker tar layers have different timestamps, accurate to one second.

  1. Find the newest timestamp in each layer
  2. Sort layers by their newest timestamp
  3. Reconstruct the container image tarball with this layer order

DIY NAS / Router

A 2-bay, low power, ARM-based NAS and router.

A custom NAS built inside a hot-swap HDD enclosure, with an acrylic side panel, using a Banana Pi BPI-R2.

Multitouch Calligraphy (Code Golf)

Use a multitouch touchscreen device and try the demo. A larger tablet sized device is suggested, but a phone works.

Touch two fingers to the screen and drag them to draw a calligraphic pen stroke.

Code golfed down to 208 bytes.


I also participated in golfing a few bytes out of @xem's MiniCodeEditor by using <iframe srcdoc="...">

An online HTML/CSS/JS playground in 62 & 142 bytes

Inspired by Codepen, JSFiddle, JSbin and dabblet

golfed by xem, p01, subzey, aemkei, rlauck, bburky, mmastrac and justecorruptio

Subreddit Gender Ratios

Estimate subreddit gender ratios by using a "random" (not great) sample of users with gender identified from Reddit flair.

Google BigQuery, D3.js, Reddit API

Mathematica CTF Writeups

Writeups for multiple cryptography and stenography CTF challenges solved with Mathematica.

Google CTF 2016: Little Bobby Application writeup

Android blind SQLi by sending Intents and a BroadcastReceiver.

CVE-2016-3105 Arbitrary code execution when converting Git repos

Mercurial 3.8.1

Mercurial prior to 3.8 allowed arbitrary code execution when using the convert extension on Git repos with hostile names. This could affect automated code conversion services that allow arbitrary repository names. This is a further side-effect of Git CVE-2015-7545. Reported and fixed by Blake Burkhart.

CVE-2016-3068 Arbitrary code execution with Git subrepos

Mercurial 3.7.3

Mercurial prior to 3.7.3 allowed URLs for Git subrepos that could result in arbitrary code execution on clone. This is a further side-effect of Git CVE-2015-7545. Reported by Blake Burkhart.

CVE-2016-3069 Arbitrary code execution when converting Git repos

Mercurial 3.7.3

Mercurial prior to 3.7.3 allowed arbitrary code execution when converting Git repos with hostile names. This could affect automated conversion services. Reported by Blake Burkhart.

Mercurial remote code execution in GitHub Importer

@bburky reported a remote code execution vulnerability in Mercurial that could be triggered during repository imports using GitHub Importer.

Git remote code execution via submodules and git-remote-ext

Git allows shell commands to be specified in ext URLs for remote repositories. For example, git clone 'ext::sh -c whoami% >&2' will execute the whoami command to try to connect to a remote repository. To protect users from accidentally trying to clone a malicious URL, Git submodule URLs were restricted to a safe set of protocols in Git v2.6.1.

Some protocols (like git-remote-ext) can execute arbitrary code found in the URL. The URLs that submodules use may come from arbitrary sources (e.g., .gitmodules files in a remote repository), and can hurt those who blindly enable recursive fetch. Restrict the allowed protocols to well known and safe ones.


The (1) git-remote-ext and (2) unspecified other remote helper programs in Git before 2.3.10, 2.4.x before 2.4.10, 2.5.x before 2.5.4, and 2.6.x before 2.6.1 do not properly restrict the allowed protocols, which might allow remote attackers to execute arbitrary code via a URL in a (a) .gitmodules file or (b) unknown other sources in a submodule.


git-submodule was restricted to a safe to set of submodules by default: GIT_ALLOW_PROTOCOL=file:git:http:https:ssh.

Additionally, inside git's http.c, libcurl was restricted to the same protocol whitelist. Libcurl's recusion depth was also limited to prevent a redirect loop from causing git to hang.

Core fonts for the Web web fonts

The Microsoft Core fonts for the Web included Andale Mono, Arial, Arial Black, Comic Sans MS, Courier New, Georgia, Impact, Times New Roman, Trebuchet MS, Verdana and Webdings as TrueType fonts. Though Microsoft no longer distributes these fonts, the old versions may still be redistributed freely. However, the EULA specifies that the fonts may not be modified in any way.

But wouldn't it be fun to use them as @font-face web fonts? But sadly the original, redistributable, format is only either .exe or .sit.hqx files...

With sufficient usage of JavaScript, random HTML5 features (blob URLs in dynamically generated stylesheet rules) and emscripten-compiled cabextract, anything is possible.

Block to Block Game

An HTML5 sliding block puzzle game

Originally written framework-less using the JavaScript Canvas 2D API directly. Rewritten in late 2017 to learn the Phaser game framework.

The original version supported both keyboard and multitouch input. The Phaser rewrite only supports keyboard input.