
CVE-2026-105221 - gist RubyGem - Élevé - MITM - Vol de jeton OAuth GitHub
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cve-2026-105221-gist-tls
gist RubyGem < 6.1.0 - defunkt
Classe : contournement de la vérification TLS (vol d'identifiants) Portée : distant (sur le chemin)
http_connection définit OpenSSL::SSL::VERIFY_NONE. Le HTTPS vers GitHub chiffre toujours, mais n'importe quel certificat est accepté. Un pair sur le chemin peut lire le jeton OAuth que la CLI envoie, puis lire et modifier les gists de la victime.
| ID | CVE-2026-105221 |
| Classe | Contournement de la vérification TLS (vol d'identifiants) |
| Portée | Distante (sur le chemin) |
| CWE | CWE-295 |
| CVSS | Élevé : 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) |
| Produit | gist |
| Affecté | 4.0.0 à 6.0.0. Version du labo 6.0.0. Corrigé dans 6.1.0 (07ccc1a). |
| Auth | MITM sur le chemin de la CLI gist |
| Licence | GNU Affero GPL v3.0 |
| Labo | 127.0.0.1 uniquement |
L'attaquant se place sur le chemin et récupère le jeton GitHub.
CN=mitm.invalid suffit.Authorization: token .... La connexion (gist --login) et l'envoi/la liste/la suppression de gists passent tous par http_connection. Le jeton dans ~/.gist transite par ce socket.gist. Gists privés, mises à jour, suppressions.Il faut une position sur le réseau : Wi-Fi hostile, un proxy, une machine au milieu. Il ne s'agit pas d'une RCE distante non authentifiée contre un serveur.
6.1.0 définit VERIFY_PEER. Le même faux certificat échoue avec certificate verify failed (self-signed certificate) et le jeton ne quitte jamais le client.
VulnCheck a publié CVE-2026-105221. Siyang Wu l'a signalée. L'issue 373 est le ticket public. La PR 374 a changé le mode de vérification. J'ai reproduit la CVE publique en labo. Il n'y avait pas de PoC public.
lib/gist.rb http_connection sur 6.0.0 :
if uri.scheme == "https"
connection.use_ssl = true
connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
6.1.0 est VERIFY_PEER.
Le labo loopback est un faux stub HTTPS GitHub Enterprise avec un certificat auto-signé. GITHUB_URL=https://127.0.0.1:8443 place gist en mode GHE (POST /api/v3/gists). Un jeton de labo CVE-2026-105221-WITNESS se trouve dans le fichier ~/.gist.* correspondant. gist 6.0.0 termine le TLS, le stub capture Authorization: token CVE-2026-105221-WITNESS et écrit le témoin. gist 6.1.0 face au même stub échoue au TLS. Le compteur de captures sur 6.1.0 reste à zéro. Rien ne communique avec api.github.com.
SUCCESS CVE-2026-105221 vuln-tls=ok token-captured=1 patched-tls=fail witness-written=yes CVE-2026-105221-WITNESS
Aucun faux pas déjà enregistré. Le premier run.sh a affiché SUCCESS. Un reverse shell. Du théâtre. L'oracle est le jeton de lab capturé sur 6.0.0 et l'erreur TLS auto-signée sur 6.1.0.
cd lab
./run.sh
Cibler uniquement https://127.0.0.1:18210 (conteneur 8443). run.sh installe gist 6.0.0 et 6.1.0 depuis RubyGems, sert le stub à l'intérieur du conteneur, puis démonte la pile. Certificat auto-signé. Pas de vrai GitHub.
Mettre à niveau la gem gist vers 6.1.0 ou une version ultérieure.
lib/gist.rb v6.0.0 L466-L468