
CVE-2026-105221 - gist RubyGem - Alta - MITM - Robo de token de GitHub OAuth
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cve-2026-105221-gist-tls
gist RubyGem < 6.1.0 - defunkt
http_connection establece OpenSSL::SSL::VERIFY_NONE. HTTPS hacia GitHub sigue cifrando, pero se acepta cualquier certificado. Un par en la ruta puede leer el token OAuth que envía la CLI, y luego leer y modificar los gists de la víctima.
| ID | CVE-2026-105221 |
| CWE | CWE-295 |
| CVSS | Alto: 7.4 CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N (VulnCheck 4.0: 9.1) |
| Producto | gist |
| Afectado | 4.0.0 hasta 6.0.0. Fijado en laboratorio 6.0.0. Corregido en 6.1.0 (07ccc1a). |
| Auth | MITM en la ruta de la CLI gist |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1 |
El atacante se sitúa en la ruta y toma el token de GitHub.
CN=mitm.invalid es suficiente.Authorization: token .... El inicio de sesión (gist --login) y las operaciones de subida/listado/borrado de gist pasan por http_connection. El token en ~/.gist viaja por ese socket.gist. Gists privados, actualizaciones, borrados.Necesitan una posición de red: Wi-Fi hostil, un proxy, una máquina en medio. Esto no es un RCE remoto no autenticado contra un servidor.
6.1.0 establece VERIFY_PEER. El mismo certificado falso muere con certificate verify failed (self-signed certificate) y el token nunca sale del cliente.
VulnCheck publicó CVE-2026-105221. Siyang Wu lo reportó. Issue 373 es el ticket público. PR 374 cambió el modo de verificación. Reproduje el CVE público en laboratorio. No había PoC público.
lib/gist.rb http_connection en 6.0.0:
if uri.scheme == "https"
connection.use_ssl = true
connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
6.1.0 es VERIFY_PEER.
El laboratorio en loopback es un stub HTTPS falso de GitHub Enterprise con un certificado autofirmado. GITHUB_URL=https://127.0.0.1:8443 pone a gist en modo GHE (POST /api/v3/gists). Un token de laboratorio CVE-2026-105221-WITNESS reside en el archivo ~/.gist.* correspondiente. gist 6.0.0 completa el TLS, el stub captura Authorization: token CVE-2026-105221-WITNESS y escribe el testigo. gist 6.1.0 contra el mismo stub falla el TLS. El contador de capturas en 6.1.0 permanece en cero. Nada se comunica con api.github.com.
SUCCESS CVE-2026-105221 vuln-tls=ok token-captured=1 patched-tls=fail witness-written=yes CVE-2026-105221-WITNESS
Caminos equivocados ya registrados: ninguno. El primer run.sh imprimió SUCCESS. Una reverse shell. Teatro. El oráculo es el token de laboratorio capturado en 6.0.0 y el error de TLS autofirmado en 6.1.0.
cd lab
./run.sh
Objetivo solo https://127.0.0.1:18210 (contenedor 8443). run.sh instala gist 6.0.0 y 6.1.0 desde RubyGems, sirve el stub dentro del contenedor y luego desmonta el stack. Certificado autofirmado. Sin GitHub real.
Actualiza la gema gist a 6.1.0 o posterior.
lib/gist.rb v6.0.0 L466-L468