Abusing Github Actions
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
In this page you will find:
A summary of all the impacts of an attacker managing to access a Github Action
Different ways to get access to an action:
Having permissions to create the action
Abusing pull request related triggers
Abusing other external access techniques
Pivoting from an already compromised repo
Finally, a section about post-exploitation techniques to abuse an action from inside (cause the mentioned impacts)
For an introduction about Github Actions check the basic information.
If you can execute arbitrary code in GitHub Actions within a repository, you may be able to:
Κλέψτε μυστικά που είναι τοποθετημένα στην pipeline και καταχραστείτε τα προνόμια της pipeline για να αποκτήσετε μη εξουσιοδοτημένη πρόσβαση σε εξωτερικές πλατφόρμες, όπως το AWS και το GCP.
Συμβιβάστε τις αναπτύξεις και άλλα αρχεία.
Αν η pipeline αναπτύσσει ή αποθηκεύει περιουσιακά στοιχεία, θα μπορούσατε να αλλάξετε το τελικό προϊόν, επιτρέποντας μια επίθεση στην αλυσίδα εφοδιασμού.
Εκτελέστε κώδικα σε προσαρμοσμένους εργαζόμενους για να καταχραστείτε την υπολογιστική ισχύ και να μεταβείτε σε άλλα συστήματα.
Επικαλύψτε τον κώδικα του αποθετηρίου, ανάλογα με τα δικαιώματα που σχετίζονται με το GITHUB_TOKEN
.
This "secret" (coming from ${{ secrets.GITHUB_TOKEN }}
and ${{ github.token }}
) is given when the admin enables this option:
This token is the same one a Github Application will use, so it can access the same endpoints: https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps
Github should release a flow that allows cross-repository access within GitHub, so a repo can access other internal repos using the GITHUB_TOKEN
.
You can see the possible permissions of this token in: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
Note that the token expires after the job has completed.
These tokens looks like this: ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7
Some interesting things you can do with this token:
Σημειώστε ότι σε πολλές περιπτώσεις θα μπορείτε να βρείτε tokens χρηστών github μέσα σε περιβάλλοντα Github Actions ή στα μυστικά. Αυτά τα tokens μπορεί να σας δώσουν περισσότερα δικαιώματα πάνω στο αποθετήριο και την οργάνωση.
Είναι δυνατόν να ελέγξετε τις άδειες που έχουν δοθεί σε ένα Github Token σε άλλα αποθετήρια χρηστών ελέγχοντας τα αρχεία καταγραφής των ενεργειών:
Αυτή θα ήταν η πιο εύκολη μέθοδος για να συμβιβαστούν οι Github actions, καθώς αυτή η περίπτωση υποθέτει ότι έχετε πρόσβαση για δημιουργία νέου αποθετηρίου στην οργάνωση, ή έχετε δικαιώματα εγγραφής σε ένα αποθετήριο.
Αν βρίσκεστε σε αυτό το σενάριο μπορείτε απλά να ελέγξετε τις Τεχνικές Μετά την Εκμετάλλευση.
Σε περίπτωση που τα μέλη μιας οργάνωσης μπορούν να δημιουργήσουν νέα αποθετήρια και μπορείτε να εκτελέσετε τις github actions, μπορείτε να δημιουργήσετε ένα νέο αποθετήριο και να κλέψετε τα μυστικά που έχουν οριστεί σε επίπεδο οργάνωσης.
Αν μπορείτε να δημιουργήσετε ένα νέο κλάδο σε ένα αποθετήριο που ήδη περιέχει μια ρυθμισμένη Github Action, μπορείτε να τροποποιήσετε αυτήν, να ανεβάσετε το περιεχόμενο και στη συνέχεια να εκτελέσετε αυτήν την ενέργεια από τον νέο κλάδο. Με αυτόν τον τρόπο μπορείτε να εξάγετε μυστικά σε επίπεδο αποθετηρίου και οργάνωσης (αλλά πρέπει να γνωρίζετε πώς ονομάζονται).
Μπορείτε να κάνετε την τροποποιημένη ενέργεια εκτελέσιμη χειροκίνητα, όταν δημιουργείται μια PR ή όταν ωθείται κάποιος κώδικας (ανάλογα με το πόσο θόρυβο θέλετε να κάνετε):
Υπάρχουν διάφοροι ενεργοποιητές που θα μπορούσαν να επιτρέψουν σε έναν επιτιθέμενο να εκτελέσει μια Github Action από άλλο αποθετήριο. Εάν αυτές οι ενεργοποιήσιμες ενέργειες είναι κακώς διαμορφωμένες, ένας επιτιθέμενος θα μπορούσε να είναι σε θέση να τις παραβιάσει.
pull_request
Ο ενεργοποιητής ροής pull_request
θα εκτελεί τη ροή κάθε φορά που λαμβάνεται ένα pull request με κάποιες εξαιρέσεις: από προεπιλογή, αν είναι η πρώτη φορά που συνεργάζεστε, κάποιος διαχειριστής θα χρειαστεί να εγκρίνει την εκτέλεση της ροής:
Καθώς ο προεπιλεγμένος περιορισμός ισχύει για πρώτους συνεισφέροντες, θα μπορούσατε να συμβάλετε διορθώνοντας ένα έγκυρο σφάλμα/τυπογραφικό λάθος και στη συνέχεια να στείλετε άλλα PRs για να εκμεταλλευτείτε τα νέα σας δικαιώματα pull_request
.
Το δοκίμασα και δεν λειτουργεί: Μια άλλη επιλογή θα ήταν να δημιουργήσετε έναν λογαριασμό με το όνομα κάποιου που συνέβαλε στο έργο και να διαγράψετε τον λογαριασμό του.
Επιπλέον, από προεπιλογή αποτρέπει τις δικαιώματα εγγραφής και πρόσβαση σε μυστικά στο στοχευμένο αποθετήριο όπως αναφέρεται στα έγγραφα:
Με την εξαίρεση του
GITHUB_TOKEN
, τα μυστικά δεν μεταφέρονται στον εκτελεστή όταν μια ροή ενεργοποιείται από ένα forked αποθετήριο. ΤοGITHUB_TOKEN
έχει δικαιώματα μόνο για ανάγνωση σε pull requests από forked αποθετήρια.
Ένας επιτιθέμενος θα μπορούσε να τροποποιήσει τον ορισμό της Github Action προκειμένου να εκτελέσει αυθαίρετα πράγματα και να προσθέσει αυθαίρετες ενέργειες. Ωστόσο, δεν θα είναι σε θέση να κλέψει μυστικά ή να αντικαταστήσει το αποθετήριο λόγω των αναφερόμενων περιορισμών.
Ναι, αν ο επιτιθέμενος αλλάξει στο PR την github action που θα ενεργοποιηθεί, η Github Action του θα είναι αυτή που θα χρησιμοποιηθεί και όχι αυτή από το αρχικό αποθετήριο!
Καθώς ο επιτιθέμενος ελέγχει επίσης τον κώδικα που εκτελείται, ακόμη και αν δεν υπάρχουν μυστικά ή δικαιώματα εγγραφής στο GITHUB_TOKEN
, ένας επιτιθέμενος θα μπορούσε για παράδειγμα να ανεβάσει κακόβουλα αρχεία.
pull_request_target
Ο ενεργοποιητής ροής pull_request_target
έχει δικαιώματα εγγραφής στο στοχευμένο αποθετήριο και πρόσβαση σε μυστικά (και δεν ζητά άδεια).
Σημειώστε ότι ο ενεργοποιητής ροής pull_request_target
εκτελείται στο βασικό πλαίσιο και όχι σε αυτό που παρέχεται από το PR (για να μην εκτελείται μη αξιόπιστος κώδικας). Για περισσότερες πληροφορίες σχετικά με το pull_request_target
ελέγξτε τα έγγραφα.
Επιπλέον, για περισσότερες πληροφορίες σχετικά με αυτή τη συγκεκριμένη επικίνδυνη χρήση, ελέγξτε αυτήν την ανάρτηση στο blog του github.
Μπορεί να φαίνεται ότι επειδή η εκτελούμενη ροή είναι αυτή που ορίζεται στη βάση και όχι στο PR, είναι ασφαλές να χρησιμοποιείτε pull_request_target
, αλλά υπάρχουν μερικές περιπτώσεις όπου δεν είναι.
Και αυτή θα έχει πρόσβαση σε μυστικά.
workflow_run
Ο ενεργοποιητής workflow_run επιτρέπει την εκτέλεση μιας ροής από μια διαφορετική όταν είναι completed
, requested
ή in_progress
.
Σε αυτό το παράδειγμα, μια ροή είναι διαμορφωμένη να εκτελείται μετά την ολοκλήρωση της ξεχωριστής ροής "Run Tests":
Moreover, according to the docs: The workflow started by the workflow_run
event is able to access secrets and write tokens, even if the previous workflow was not.
This kind of workflow could be attacked if it's depending on a workflow that can be triggered by an external user via pull_request
or pull_request_target
. A couple of vulnerable examples can be found this blog. The first one consist on the workflow_run
triggered workflow downloading out the attackers code: ${{ github.event.pull_request.head.sha }}
The second one consist on passing an artifact from the untrusted code to the workflow_run
workflow and using the content of this artifact in a way that makes it vulnerable to RCE.
workflow_call
TODO
TODO: Check if when executed from a pull_request the used/downloaded code if the one from the origin or from the forked PR
We have mentioned all the ways an external attacker could manage to make a github workflow to execute, now let's take a look about how this executions, if bad configured, could be abused:
In the case of pull_request
, the workflow is going to be executed in the context of the PR (so it'll execute the malicious PRs code), but someone needs to authorize it first and it will run with some limitations.
In case of a workflow using pull_request_target
or workflow_run
that depends on a workflow that can be triggered from pull_request_target
or pull_request
the code from the original repo will be executed, so the attacker cannot control the executed code.
However, if the action has an explicit PR checkout that will get the code from the PR (and not from base), it will use the attackers controlled code. For example (check line 12 where the PR code is downloaded):
The potentially untrusted code is being run during npm install
or npm build
as the build scripts and referenced packages are controlled by the author of the PR.
A github dork to search for vulnerable actions is: event.pull_request pull_request_target extension:yml
however, there are different ways to configure the jobs to be executed securely even if the action is configured insecurely (like using conditionals about who is the actor generating the PR).
Note that there are certain github contexts whose values are controlled by the user creating the PR. If the github action is using that data to execute anything, it could lead to arbitrary code execution:
Gh Actions - Context Script InjectionsFrom the docs: You can make an environment variable available to any subsequent steps in a workflow job by defining or updating the environment variable and writing this to the GITHUB_ENV
environment file.
If an attacker could inject any value inside this env variable, he could inject env variables that could execute code in following steps such as LD_PRELOAD or NODE_OPTIONS.
For example (this and this), imagine a workflow that is trusting an uploaded artifact to store its content inside GITHUB_ENV
env variable. An attacker could upload something like this to compromise it:
As mentioned in this blog post, this Github Action allows to access artifacts from different workflows and even repositories.
The thing problem is that if the path
parameter isn't set, the artifact is extracted in the current directory and it can override files that could be later used or even executed in the workflow. Therefore, if the Artifact is vulnerable, an attacker could abuse this to compromise other workflows trusting the Artifact.
Example of vulnerable workflow:
Αυτό θα μπορούσε να επιτεθεί με αυτή τη ροή εργασίας:
Εάν ένας λογαριασμός αλλάξει όνομα, ένας άλλος χρήστης θα μπορούσε να εγγραφεί με αυτό το όνομα μετά από κάποιο χρονικό διάστημα. Εάν ένα αποθετήριο είχε λιγότερα από 100 αστέρια πριν την αλλαγή ονόματος, το Github θα επιτρέψει στον νέο εγγεγραμμένο χρήστη με το ίδιο όνομα να δημιουργήσει ένα αποθετήριο με το ίδιο όνομα όπως αυτό που διαγράφηκε.
Έτσι, εάν μια ενέργεια χρησιμοποιεί ένα αποθετήριο από έναν ανύπαρκτο λογαριασμό, είναι ακόμα δυνατόν ένας επιτιθέμενος να δημιουργήσει αυτόν τον λογαριασμό και να συμβιβάσει την ενέργεια.
Εάν άλλα αποθετήρια χρησιμοποιούσαν εξαρτήσεις από αυτά τα αποθετήρια του χρήστη, ένας επιτιθέμενος θα είναι σε θέση να τα απαγάγει. Εδώ έχετε μια πιο ολοκληρωμένη εξήγηση: https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/
Σε αυτή την ενότητα θα μιλήσουμε για τεχνικές που θα επιτρέψουν να περάσουμε από ένα αποθετήριο σε άλλο, υποθέτοντας ότι έχουμε κάποια πρόσβαση στο πρώτο (ελέγξτε την προηγούμενη ενότητα).
Μια cache διατηρείται μεταξύ των εκτελέσεων ροής εργασίας στην ίδια κλάδο. Αυτό σημαίνει ότι εάν ένας επιτιθέμενος συμβιβάσει ένα πακέτο που αποθηκεύεται στη cache και κατεβάζεται και εκτελείται από μια πιο προνομιούχα ροή εργασίας, θα είναι σε θέση να συμβιβάσει και αυτή τη ροή εργασίας.
GH Actions - Cache PoisoningΟι ροές εργασίας θα μπορούσαν να χρησιμοποιούν artifacts από άλλες ροές εργασίας και ακόμη και αποθετήρια, εάν ένας επιτιθέμενος καταφέρει να συμβιβάσει την Github Action που ανεβάζει ένα artifact που χρησιμοποιείται αργότερα από μια άλλη ροή εργασίας, θα μπορούσε να συμβιβάσει τις άλλες ροές εργασίας:
Gh Actions - Artifact PoisoningΕλέγξτε τις παρακάτω σελίδες:
AWS - Federation AbuseGCP - Federation AbuseΕάν εισάγετε περιεχόμενο σε ένα σενάριο, είναι ενδιαφέρον να γνωρίζετε πώς μπορείτε να αποκτήσετε πρόσβαση σε μυστικά:
Εάν το μυστικό ή το token έχει οριστεί σε μια μεταβλητή περιβάλλοντος, μπορεί να προσπελαστεί άμεσα μέσω του περιβάλλοντος χρησιμοποιώντας printenv
.
Αν το μυστικό χρησιμοποιείται άμεσα σε μια έκφραση, το παραγόμενο shell script αποθηκεύεται στον δίσκο και είναι προσβάσιμο.
cat /home/runner/work/_temp/*
Για μια προσαρμοσμένη ενέργεια, ο κίνδυνος μπορεί να διαφέρει ανάλογα με το πώς ένα πρόγραμμα χρησιμοποιεί το μυστικό που απέκτησε από το επιχείρημα:
Ο τρόπος για να βρείτε ποιες Github Actions εκτελούνται σε υποδομή εκτός Github είναι να αναζητήσετε runs-on: self-hosted
στη διαμόρφωση yaml της Github Action.
Οι αυτοφιλοξενούμενοι εκτελεστές μπορεί να έχουν πρόσβαση σε επιπλέον ευαίσθητες πληροφορίες, σε άλλα δικτυακά συστήματα (ευάλωτα σημεία στο δίκτυο; υπηρεσία μεταδεδομένων;) ή, ακόμη και αν είναι απομονωμένοι και καταστραφούν, περισσότερες από μία ενέργειες μπορεί να εκτελούνται ταυτόχρονα και η κακόβουλη μπορεί να κλέψει τα μυστικά της άλλης.
Σε αυτοφιλοξενούμενους εκτελεστές είναι επίσης δυνατό να αποκτηθούν τα μυστικά από τη διαδικασία _Runner.Listener_** που θα περιέχει όλα τα μυστικά των ροών εργασίας σε οποιοδήποτε βήμα, εκχυλίζοντας τη μνήμη της:
Δείτε αυτή την ανάρτηση για περισσότερες πληροφορίες.
Είναι δυνατόν να δημιουργήσετε Github actions που θα κατασκευάσουν και θα αποθηκεύσουν μια εικόνα Docker μέσα στο Github. Ένα παράδειγμα μπορεί να βρεθεί στην παρακάτω επεκτάσιμη ενότητα:
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)