I vårt forrige innlegg om CI/CD Pipelines, vi så hvordan hacke en CI/CD scenario som antagelig var beskyttet.
La oss huske poenget vårt i forrige innlegg: vi startet med noen pipeline som var sårbar for Indirekte forgiftning Pipeline Gjennomføring (I-PPE) og for å fikse det bestemte vi oss for å dele opp pipeline i to:
- Den første pipeline (Bygge-CI), trygt for D-PPE og I-PPE, ville sjekke PR-koden, lage bygget og generere en artefakt
- Den 2ende pipeline (Test CI), også trygt for D-PPE og I-PPE ville sjekke ut basiskoden (for å unngå modifikasjon av skallskript) og kjøre de originale skriptene mot artefakten.
- For å synkronisere test-CI pipeline å kjøre ETTER Build CI pipeline, vi brukte arbeidsflytkjøring avtrekker.
Vi kalte dette scenario #3.

Selv om det, som vi nevnte i det innlegget, finnes andre løsninger, bestemte vi oss for å implementere denne «løsningen» av pedagogiske årsaker, slik at vi kan dykke dypt ned i sårbarheter ved CI/CD pipelines.
Etterpå så vi hvordan vi kunne hacke dette scenarioet ved å forgiftning av gjenstandenDette er hva vi kaller Artefaktforgiftning, dvs. muligheten til å modifisere (hacke) pipeline logikk ved å modifisere en pipeline gjenstand.
Hva er problemet med denne tilnærmingen? Vi så at problemet oppstår når en bruker «oppretter» en ny pipeline.
Hvis en bruker åpner en PR som inneholder en ny pipeline, GitHub vil utføre det pipeline (gitt noen betingelser, som vi så i innlegget).
Brukeren kan deretter opprette en ny pipeline med samme navn som Build CI!! Ja, det er overraskende, men GitHub lar deg lage to pipelinemed samme navn!!
Når brukeren åpner en PR med disse endringene, den «nye» pipeline vil bli henrettet (laster opp en forgiftet gjenstand) og Deploy CI pipeline vil bli utført etter det, noe som resulterer i at det «modifiserte» skallskriptet overskriver det «originale» skallskriptet som ligger i pipeline arbeidsområde. Så denne «løsningen» unngår ikke sårbarheten i I-PPE (som vi kan se nedenfor)

Hva er problemene? Det er i det minste et par problemer:
- Først Hvordan kan man være sikker på at byggeprosessen ikke har blitt tuklet med? I dette scenariet har den ondsinnede brukeren vært i stand til å endre den tiltenkte byggeprosessen ved å bruke sin pipeline å lage en forgiftet gjenstand.
- Dernest, Hvordan kan vi vurdere proveniensen til en gjenstand?
Disse spørsmålene kaster oss i armene på Programvareattesteringer domene!!
Programvareattesteringer
An attestasjon er et stykke av dato representerer bevis på en hendelseI den virkelige verden kaller vi vanligvis disse sertifiseringer.
Når for eksempel et laboratorium tester blodet ditt, registreres og bekreftes data om testen. Blodprøveresultatene etterprøvbar og sporbar.

Nærmere vårt IT-domene kan du gjette hva som ville være en oversettelse av denne prosessen til for eksempel en kompileringsprosess.

Informasjon om kompileringsservermiljøet og verktøyene, materialene (kildekoden) og produktene/artefaktene (binærkoden) vil være en del av en slik attestering.
Attestasjonen må selvsagt genereres av en autorisert attestant (autentisert og ikke-repudierbar) for å gi troverdighet.
Sannsynligvis tenker noen av dere ... og hva er det forskjellen mellom signaturer og attester?
Kodesignaturer og attester
På et høyt nivå, en signatur opprettes ved hjelp av et nøkkelpar og en artefakt. Nøkkelparet består av en offentlig nøkkel og en privat nøkkel.

Brukeren signerer en artefakt med den private nøkkelen, og andre kan deretter bekrefte signaturen med den offentlige nøkkelen. Den private nøkkelen må holdes hemmelig, men den offentlige nøkkelen distribueres vidt.
Signaturer kan brukes å bevise at innehaveren av den private nøkkelen brukte den private nøkkelen til å signere artefakten.
signaturer ikke bevis
- Brukerens intensjon å signere gjenstanden (de kan ha blitt lurt), eller
- Brukerens intensjon om å foreta seg noe spesifikk påstand om gjenstanden
Med Attester, i stedet for å signere en artefakt direkte, oppretter brukerne en slags dokument Det fanger opp intensjonen deres bak signeringen av gjenstanden og eventuelle spesifikke krav blir laget som en del av denne signaturen.
In-toto-attesteringsrammeverk
Det vanligste rammeverket er in-toto-attesteringsrammeverk
- definerer en standard format for attester som binder subjektene, artefaktene som beskrives, til autentiserte metadata om artefakten
- gir et sett med forhåndsdefinerte predikater for å kommunisere autentiserte metadata på tvers av programvareforsyningskjeder
La oss gå litt nærmere inn på attesteringsformatet.
An attestasjon er en digitalt signert dokument som inneholder Uttalelser.
Ocuco Uttalelse er det midterste laget av attestasjonen, som binder den til en bestemt Emne og entydig identifisere typene av predikat:
- Emne: The kryptografisk sikker referanse til artefaktet (vanligvis via en hash), og
- Predikateret sett med spesifikke krav om den artefakten kalles en påstand. Disse påstandene kan brukes til å uttrykke (og senere bevise) hva som helst du kan tenke deg! De kan representere manuell godkjenning, artefaktens opprinnelse, automatiserte testresultater, et revisjonsspor eller mer!
Når denne erklæringen er kryptografisk signert, blir den referert til som en attestasjon

På denne måten, som et eksempel, oppretter Alice en erklæring om en artefakt og signerer den med sin private nøkkel, og oppretter dermed en attestasjon.
- Bob kan da bekrefte signaturen i den attestasjonen, som tillater ham å stole på påstandene innsiden.
Bob kan deretter bruke disse påstandene å bestemme om man skal tillate bruk av denne gjenstanden eller ikke.

Kan attester bidra til å løse problemer med gjenstandsforgiftning?
Etter denne introduksjonen til attestasjoner, la oss gå tilbake til problemet vårt. Hvordan kan attester hjelpe oss med å løse problemet vårt, dvs. å unngå gjenstandsforgiftning?
Den ondsinnede brukeren var i stand til å lage en artefakt som omgikk den «offisielle» mekanismen, dvs. ved å bruke sin pipeline for å generere artefaktet.
Det hadde vært fantastisk om vi kunne bevise at artefaktene som lastes ned har blitt bygget med den offisielle pipelines. Dette er bare ett eksempel på det vi kan kalle «manipuleringspunkter», men det kan finnes mange andre.

Som du kan se på bildet ovenfor, er det flere manipuleringspunkter. På denne måten kan forbrukeren pipeline (Test-CI i vårt eksempel) må vurdere integriteten til byggeprosessen samt integriteten til selve gjenstanden.
I vårt eksempel er den forgiftede gjenstanden skapt ved å introdusere en ny (forgiftet) pipeline som tukler med byggeprosessen. Men den ondsinnede brukeren kunne ha vært i stand til å:
- endre koden etter at den er sjekket ut fra SCM å generere en ondsinnet binærfil
- erstatt den riktige binærfilen produsert av kompileringen med en hvilken som helst annen skadelig binærfil
- kompromittere artefaktregisteret og laste opp en forgiftet artefakt bygget på en annen måte
- og så videre
Som du kan se, kan det være flere "manipuleringspunkter".
Hva er viktig her? Åpenbart å beskytte alle disse «manipuleringspunktene». Men til syvende og sist er det viktigste at «forbrukeren» av gjenstanden kan vurdere gjenstandens integritet og bestemme om de skal gå videre med den eller ikke.
Vi kan vurdere integriteten til en gjenstand på to måter.
Det ene er ved å vurdere proveniens av gjenstanden.
Ved å generere en Proveniensbekreftelse, tilbyr vi nyttige metadata (riktig autentisert og ikke-avkreftet) om artefaktet. I de følgende eksemplene vil vi bruke Xygeni SALT (Software Attestations Layer for Trust), komponenten for å generere, registrere og verifisere programvareattestasjoner.

- name: Building ...
run: |
# mvn will compile and create target/MyApp.war
mvn clean package
- name: Generating provenance
run: |
#!/usr/bin/env bash
shopt -s expand_aliases
alias salt=$PWD/salt_pro/xygeni_salt/salt
echo " "
echo "-----------"
echo "Generating Provenance with CLI ..."
salt at slsa \
--basedir ${GITHUB_WORKSPACE}/target \
--key="${PRIVATE_KEY}" \
--public-key=${GITHUB_WORKSPACE}/Test1_public.pem \
--key-password=${KEY_PASSWD} \
--output-unsigned=${GITHUB_WORKSPACE}/cli_provenance_${PIPELINE}_unsigned.json \
--pipeline ${PIPELINE} --pretty-print \
--file ./MyApp.war
I koden ovenfor kan du se at det er et trinn som bygger war-filen og et andre trinn som genererer ProveniensbekreftelseFor å gjøre det, den pipeline bruker den private nøkkelen og inkluderer også den offentlige nøkkelen i attestasjonen.
Bak kulissene, Xygenis salt kommandoen lagrer attesteringen i en hovedbok (også kjent som et attestasjonsregister, posten i vårt tilfelle, men du kan bruke hvilken som helst annen). Gjort det, forbrukeren pipeline kan inkludere Xygenis Verifiseringsmotor for å bekrefte gjenstandens opprinnelse og vurdere gjenstandens integritet.
- name: 'Verifying the attestation'
run: |
#!/usr/bin/bash
echo " "
echo "-------"
# Calculate sha256sum for the artifact
SHA_SUM=$(sha256sum ./MyApp.war | cut -f1 -d ' ')
# Recover the attestation Id from the sha256sum
ATT_ID=$(echo $(salt -q registry search --digest sha256:$SHA_SUM --format json) | jq -r .[-1].gitoidSha256)
echo " "
echo "-------"
# Download the provenance attestation
echo "Downloading the provenance attestation ..."
salt -q reg get --id=$ATT_ID --format=json > ${GITHUB_WORKSPACE}/provenance_kk.signed.json
echo " "
echo "-------"
echo "Verifying provenance ..."
salt verify \
--basedir ${GITHUB_WORKSPACE} \
--attestation=${GITHUB_WORKSPACE}/provenance_kk.signed.json \
--public-key=${GITHUB_WORKSPACE}/Test1_public.pem \
--file ./MyApp.war
Verifiseringsprosessen vurderer:
- Ocuco artefakt sha256sum er gyldig (dvs. det finnes en bekreftelse om det «emnet»), og
- Ocuco attestasjonen er korrekt autentisert (den er generert ved bruk av riktig privatnøkkel)
Denne verifiseringsprosessen kan deretter vurdere at både artefaktet og attestasjonen er gyldige.
Men, som du husker, i vårt tilfelle ble artefakten generert av en «ondsinnet» pipeline (dvs. ikke originalen med en modifisert pipeline). Så må vi gå videre og sjekke et annet aspekt: at gjenstanden er generert av «originalen» pipeline, ikke noen annen.
For å gjøre det, bare legg til en enkel linje for å sjekke for den tilstanden, for eksempel:
echo " "
echo "-------"
# Download the provenance attestation
echo "Downloading the provenance attestation ..."
salt -q reg get --id=$ATT_ID --format=json > ${GITHUB_WORKSPACE}/provenance_kk.signed.json
WFR=$(jq -r .payload ${GITHUB_WORKSPACE}/provenance_kk.signed.json |base64 -d | jq -r .predicate.buildDefinition.internalParameters.environment.GITHUB_WORKFLOW_REF)
echo $WFR | grep cicd_top10_3_salt\/.github\/workflows\/build.yml
Denne tilleggskontrollen vil mislykkes hvis artefakten ikke ble generert av vår «sikre» pipeline.
Hvis artefakten ble generert av vår originale pipeline (cicd_top10_3_salt/.github/workflows/build.yml), vil grep-kommandoen lykkes, ellers vil den mislykkes og ødelegge pipeline og avbryter eventuelle ytterligere trinn.
«Byggeren» pipeline er bare ett sabotasjepunkt å sjekke, men som nevnt tidligere er det noen andre sabotasjepunkter vi bør sjekke.
For eksempel, Hva om kildekoden har blitt tuklet med etter utsjekking av repoet og før byggekommandoen? I dette tilfellet er ikke koden som skal bygges den samme som er lagret i SCM.
Å sjekke dette manipuleringspunktet er så enkelt som å sjekke materialets hash-verdier i hvert trinn.
SHA_ATT_MATERIAL=$(jq -r .payload ${GITHUB_WORKSPACE}/provenance_kk.signed.json | base64 -d | jq -r .predicate.attestations[0].predicate.materials[].digest[])
SHA_STEP_MATERIAL=$(jq -r .payload ${GITHUB_WORKSPACE}/provenance_kk.signed.json | base64 -d | jq -r .predicate.attestations[3].predicate.materials[0].digest[])
Konklusjoner
Oppsummert, en Programvareattestering er en påstand fremsatt om et program, dvs. en autentisert uttalelse (metadata) om en programvareartefakt eller en samling av programvareartefakter.
Programvareattesteringer er en generalisering av rå artefakt-/kodesignering. Attestasjonen er et signert dokument (i et gitt format, vanligvis basert på JSON) som knytter metadata til en artefakt. De representerer bevis som knytter sammen input (materialer) og output (produserte artefakter) ved hvert byggetrinn.
Attesteringer gir en verifiserbar oversikt over trinnene som er utført for å bygge de endelige programvareartefaktene, inkludert inndatamaterialer for hvert trinn og kjørte byggekommandoer.
Avslutningsvis er programvareattesteringer en flott mekanisme for å sjekke mange forskjellige integritetsaspekter ved byggeprosessen vår.
Ferdig med serien? Ikke bekymre deg! Gå gjerne tilbake til 'Forgiftet Pipeline Henrettelse (PPE)' eller et hvilket som helst annet innlegg som vekker interessen din igjen!
Følg med, vi skal dykke dypt ned i programvareattesteringer og build security i videre blogginnlegg.







