当前位置: 首页 > news >正文

Python 实战:内网渗透中的信息收集自动化脚本(9)

用途限制声明,本文仅用于网络安全技术研究、教育与知识分享。文中涉及的渗透测试方法与工具,严禁用于未经授权的网络攻击、数据窃取或任何违法活动。任何因不当使用本文内容导致的法律后果,作者及发布平台不承担任何责任。渗透测试涉及复杂技术操作,可能对目标系统造成数据损坏、服务中断等风险。读者需充分评估技术能力与潜在后果,在合法合规前提下谨慎实践。

这次我们使用python来编写一个跨平台的批量用户密码修改工具,支持 Windows 和 Linux 系统。它能够根据配置批量修改符合条件的用户密码,同时具备权限检查、用户信息备份、操作日志记录和模拟运行(不实际修改密码)等功能,适用于系统管理员批量管理用户密码的场景。

import platform
import logging
import subprocess
import ctypes
import os
from typing import List, Dict, Optional# 配置日志:记录操作详情(成功/失败/时间),支持文件和控制台输出
logging.basicConfig(level=logging.INFO,format="%(asctime)s - %(levelname)s - %(message)s",handlers=[logging.FileHandler("password_change.log"),  # 日志文件备份logging.StreamHandler()  # 控制台输出]
)
logger = logging.getLogger(__name__)class PasswordChanger:def __init__(self, config: Dict):"""初始化配置参数"""self.target_users = config.get("target_users", [])  # 目标用户列表(支持正则)self.new_password = config.get("new_password")  # 新密码self.backup_enabled = config.get("backup_enabled", True)  # 是否备份用户信息self.dry_run = config.get("dry_run", False)  # 模拟运行(不实际修改)self._validate_config()  # 校验配置合法性def _validate_config(self) -> None:"""校验配置参数合法性"""if not self.target_users:raise ValueError("目标用户列表不能为空,请配置target_users")if not self.new_password:raise ValueError("新密码不能为空,请配置new_password")if len(self.new_password) < 8:logger.warning("密码长度小于8位,可能不符合安全策略")def _is_admin(self) -> bool:"""检查当前用户是否有管理员/root权限(修改密码必需)"""try:if platform.system() == "Windows":return ctypes.windll.shell32.IsUserAnAdmin() != 0else:  # Linux/Unixreturn os.geteuid() == 0except Exception as e:logger.error(f"权限检查失败: {str(e)}")return Falsedef _backup_user_info(self, username: str) -> None:"""备份用户信息(用于回滚)"""if not self.backup_enabled:returntry:if platform.system() == "Windows":# Windows: 备份用户基本信息到文件with open(f"user_backup_{username}.txt", "w") as f:f.write(f"Backup for {username} at {platform.system()}\n")# 可扩展:通过WMI获取更多用户属性(如SID、创建时间等)else:# Linux: 备份/etc/shadow中该用户的记录with open("/etc/shadow", "r") as shadow, \open(f"shadow_backup_{username}.txt", "w") as f:for line in shadow:if line.startswith(f"{username}:"):f.write(line)breaklogger.info(f"已备份用户 {username} 信息")except Exception as e:logger.warning(f"备份用户 {username} 信息失败: {str(e)}")def _match_user(self, username: str) -> bool:"""判断用户是否符合修改条件(支持精确匹配和正则)"""import refor pattern in self.target_users:if re.fullmatch(pattern, username):  # 支持正则表达式匹配return Truereturn Falsedef set_windows_password(self, username: str) -> bool:"""Windows系统修改密码(优化错误处理)"""try:from win32com import adsifrom pywintypes import com_error  # 捕获ADSI相关异常ads_path = f"WinNT://localhost/{username},user"ads_obj = adsi.ADsGetObject(ads_path)ads_obj.Getinfo()if not self.dry_run:ads_obj.SetPassword(self.new_password)logger.info(f"[Windows] 用户 {username} 密码修改成功({'模拟' if self.dry_run else '实际'}操作)")return Trueexcept com_error as e:error_msg = f"[Windows] 用户 {username} 密码修改失败: {e.excepinfo[2]}"logger.error(error_msg)return Falseexcept Exception as e:logger.error(f"[Windows] 处理用户 {username} 时发生未知错误: {str(e)}")return Falsedef set_linux_password(self, username: str) -> bool:"""Linux系统修改密码(使用subprocess增强安全性,避免shell注入)"""try:# 构造密码输入(两次输入新密码)input_data = f"{self.new_password}\n{self.new_password}\n".encode()# 使用subprocess避免os.system的安全风险,不启用shellresult = subprocess.run(["passwd", username],  # 命令参数列表化,防止注入input=input_data,stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=False  # 二进制输入输出)if result.returncode == 0:logger.info(f"[Linux] 用户 {username} 密码修改成功({'模拟' if self.dry_run else '实际'}操作)")return Trueelse:error_msg = result.stderr.decode(errors="ignore")logger.error(f"[Linux] 用户 {username} 密码修改失败: {error_msg}")return Falseexcept Exception as e:logger.error(f"[Linux] 处理用户 {username} 时发生未知错误: {str(e)}")return Falsedef run(self) -> None:"""主执行逻辑"""# 权限检查if not self._is_admin():logger.error("错误:修改用户密码需要管理员/root权限,请以管理员身份运行")return# 按系统类型处理if platform.system() == "Windows":self._process_windows_users()else:self._process_linux_users()def _process_windows_users(self) -> None:"""处理Windows用户"""try:import wmiw = wmi.WMI()for user in w.Win32_UserAccount():username = user.Nameif self._match_user(username):logger.info(f"发现符合条件的用户: {username}")self._backup_user_info(username)self.set_windows_password(username)except ImportError:logger.error("处理Windows用户失败:请安装wmi模块(pip install wmi)")except Exception as e:logger.error(f"Windows用户处理逻辑出错: {str(e)}")def _process_linux_users(self) -> None:"""处理Linux用户(优化用户筛选逻辑)"""try:import pwd# 筛选有效用户(排除系统用户,可配置uid范围)min_uid = 1000  # 普通用户起始UID(可配置)for p in pwd.getpwall():if p.pw_uid == 0 or (p.pw_uid >= min_uid and p.pw_uid < 65534):username = p.pwd_nameif self._match_user(username):logger.info(f"发现符合条件的用户: {username}")self._backup_user_info(username)self.set_linux_password(username)except Exception as e:logger.error(f"Linux用户处理逻辑出错: {str(e)}")if __name__ == "__main__":# 配置示例(可迁移到外部配置文件,如JSON/YAML)config = {"target_users": ["testuser", "user1", "dev_.*"],  # 支持正则(如匹配dev_开头的用户)"new_password": "StrongPass@2024",  # 强密码(实际使用中建议从环境变量读取)"backup_enabled": True,  # 启用备份"dry_run": False  # 设为True可先模拟运行,不实际修改密码}try:changer = PasswordChanger(config)changer.run()except Exception as e:logger.critical(f"程序执行失败: {str(e)}", exc_info=True)
1. 导入模块与日志配置
import platform  # 判断操作系统类型
import logging  # 日志记录
import subprocess  # 执行系统命令(如Linux的passwd)
import ctypes  # Windows权限检查
import os  # 系统操作(如文件、权限)
from typing import List, Dict, Optional  # 类型提示,增强代码可读性# 配置日志:同时输出到文件和控制台,记录操作时间、级别和内容
logging.basicConfig(level=logging.INFO,format="%(asctime)s - %(levelname)s - %(message)s",handlers=[logging.FileHandler("password_change.log"),  # 日志保存到文件logging.StreamHandler()  # 日志打印到控制台]
)
logger = logging.getLogger(__name__)  # 创建日志实例
  • 导入的模块覆盖了跨平台判断、日志、系统命令执行等核心需求。
  • 日志配置确保所有操作(成功 / 失败 / 时间)都被记录,方便后续审计和问题排查。
2. 核心类 PasswordChanger

该类封装了密码修改的所有逻辑,通过配置参数初始化,支持灵活定制。

2.1 初始化与配置校验
class PasswordChanger:def __init__(self, config: Dict):"""初始化配置参数"""self.target_users = config.get("target_users", [])  # 目标用户列表(支持正则)self.new_password = config.get("new_password")  # 新密码self.backup_enabled = config.get("backup_enabled", True)  # 是否备份用户信息self.dry_run = config.get("dry_run", False)  # 模拟运行(不实际修改)self._validate_config()  # 校验配置合法性def _validate_config(self) -> None:"""校验配置参数合法性"""if not self.target_users:raise ValueError("目标用户列表不能为空,请配置target_users")if not self.new_password:raise ValueError("新密码不能为空,请配置new_password")if len(self.new_password) < 8:logger.warning("密码长度小于8位,可能不符合安全策略")
  • __init__ 从配置中读取核心参数:目标用户、新密码、备份开关、模拟运行开关。
  • _validate_config 确保配置合法:必须指定目标用户和新密码,同时警告短密码(可能不符合安全策略)。
2.2 权限检查
def _is_admin(self) -> bool:"""检查当前用户是否有管理员/root权限(修改密码必需)"""try:if platform.system() == "Windows":return ctypes.windll.shell32.IsUserAnAdmin() != 0  # Windows管理员判断else:  # Linux/Unixreturn os.geteuid() == 0  # root用户判断(euid=0)except Exception as e:logger.error(f"权限检查失败: {str(e)}")return False
  • 修改用户密码需要高权限(Windows 管理员 / Linux root),该方法提前检查权限,避免后续操作失败。
2.3 用户信息备份
def _backup_user_info(self, username: str) -> None:"""备份用户信息(用于回滚)"""if not self.backup_enabled:returntry:if platform.system() == "Windows":# Windows:备份用户基本信息到文本文件with open(f"user_backup_{username}.txt", "w") as f:f.write(f"Backup for {username} at {platform.system()}\n")# 可扩展:通过WMI获取更多属性(如SID、创建时间)else:# Linux:备份/etc/shadow中该用户的密码记录(用于密码回滚)with open("/etc/shadow", "r") as shadow, \open(f"shadow_backup_{username}.txt", "w") as f:for line in shadow:if line.startswith(f"{username}:"):f.write(line)breaklogger.info(f"已备份用户 {username} 信息")except Exception as e:logger.warning(f"备份用户 {username} 信息失败: {str(e)}")
  • 开启备份时,会保存用户关键信息(Linux 的/etc/shadow记录包含密码哈希,Windows 保存基本信息),便于密码修改出错时回滚。
2.4 用户匹配逻辑
def _match_user(self, username: str) -> bool:"""判断用户是否符合修改条件(支持精确匹配和正则)"""import refor pattern in self.target_users:if re.fullmatch(pattern, username):  # 正则全匹配(如"dev_.*"匹配dev开头的用户)return Truereturn False
  • 支持通过正则表达式匹配用户(如配置["dev_.*"]可匹配所有dev_开头的用户),灵活筛选目标用户。
2.5 密码修改实现(分系统)
def set_windows_password(self, username: str) -> bool:"""Windows系统修改密码"""try:from win32com import adsi  # 操作Windows AD服务接口from pywintypes import com_error  # 捕获ADSI相关异常ads_path = f"WinNT://localhost/{username},user"  # 用户ADSI路径ads_obj = adsi.ADsGetObject(ads_path)ads_obj.Getinfo()if not self.dry_run:  # 非模拟运行时才实际修改ads_obj.SetPassword(self.new_password)logger.info(f"[Windows] 用户 {username} 密码修改成功({'模拟' if self.dry_run else '实际'}操作)")return Trueexcept com_error as e:error_msg = f"[Windows] 用户 {username} 密码修改失败: {e.excepinfo[2]}"logger.error(error_msg)return Falseexcept Exception as e:logger.error(f"[Windows] 处理用户 {username} 时发生未知错误: {str(e)}")return Falsedef set_linux_password(self, username: str) -> bool:"""Linux系统修改密码(避免shell注入风险)"""try:# 构造密码输入(passwd命令需要两次输入新密码)input_data = f"{self.new_password}\n{self.new_password}\n".encode()# 使用subprocess调用passwd,参数列表化(防止shell注入)result = subprocess.run(["passwd", username],  # 命令参数拆分,避免注入input=input_data,stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=False  # 二进制输入输出)if result.returncode == 0:  # 命令执行成功(返回码0)logger.info(f"[Linux] 用户 {username} 密码修改成功({'模拟' if self.dry_run else '实际'}操作)")return Trueelse:error_msg = result.stderr.decode(errors="ignore")logger.error(f"[Linux] 用户 {username} 密码修改失败: {error_msg}")return Falseexcept Exception as e:logger.error(f"[Linux] 处理用户 {username} 时发生未知错误: {str(e)}")return False
  • Windows:通过win32com.adsi操作 Windows 用户对象,调用SetPassword修改密码。
  • Linux:通过subprocess调用系统passwd命令,参数列表化避免 shell 注入风险(安全最佳实践)。
  • 均支持dry_run(模拟运行):仅日志记录,不实际修改密码,方便测试。
2.6 主执行逻辑
def run(self) -> None:"""主执行逻辑"""# 权限检查:无权限则退出if not self._is_admin():logger.error("错误:修改用户密码需要管理员/root权限,请以管理员身份运行")return# 按系统类型处理用户if platform.system() == "Windows":self._process_windows_users()else:self._process_linux_users()def _process_windows_users(self) -> None:"""处理Windows用户:获取所有用户,筛选并修改密码"""try:import wmi  # Windows管理接口,用于获取用户列表w = wmi.WMI()for user in w.Win32_UserAccount():  # 遍历所有本地用户username = user.Nameif self._match_user(username):  # 匹配目标用户logger.info(f"发现符合条件的用户: {username}")self._backup_user_info(username)  # 备份信息self.set_windows_password(username)  # 修改密码except ImportError:logger.error("处理Windows用户失败:请安装wmi模块(pip install wmi)")except Exception as e:logger.error(f"Windows用户处理逻辑出错: {str(e)}")def _process_linux_users(self) -> None:"""处理Linux用户:筛选普通用户,修改密码"""try:import pwd  # Linux用户信息模块min_uid = 1000  # 普通用户起始UID(排除系统用户,如root是0)for p in pwd.getpwall():  # 遍历所有用户# 筛选有效用户:root(uid=0)或普通用户(uid 1000-65533)if p.pw_uid == 0 or (p.pw_uid >= min_uid and p.pw_uid < 65534):username = p.pwd_nameif self._match_user(username):  # 匹配目标用户logger.info(f"发现符合条件的用户: {username}")self._backup_user_info(username)  # 备份信息self.set_linux_password(username)  # 修改密码except Exception as e:logger.error(f"Linux用户处理逻辑出错: {str(e)}")
  • run:主入口,先检查权限,再根据操作系统调用对应处理方法。
  • _process_windows_users:通过wmi模块获取 Windows 本地用户,筛选符合条件的用户并执行备份和密码修改。
  • _process_linux_users:通过pwd模块获取 Linux 用户,排除系统用户(保留 root 和普通用户),再执行后续操作。
3. 主程序入口
if __name__ == "__main__":# 配置示例(可迁移到外部配置文件,如JSON/YAML)config = {"target_users": ["testuser", "user1", "dev_.*"],  # 目标用户(支持正则)"new_password": "StrongPass@2024",  # 新密码(建议从环境变量读取,避免硬编码)"backup_enabled": True,  # 启用备份"dry_run": False  # 模拟运行开关(True:不实际修改)}try:changer = PasswordChanger(config)changer.run()except Exception as e:logger.critical(f"程序执行失败: {str(e)}", exc_info=True)  # 记录致命错误及堆栈

  • 定义配置示例,创建PasswordChanger实例并执行密码修改流程。
  • 捕获全局异常,确保程序崩溃时记录详细错误信息(便于排查)。

提示:此python脚本需要在管理员权限进行运行。


文章转载自:

http://2PxkEzzc.kdbcx.cn
http://vWveUrTR.kdbcx.cn
http://jZsaRukR.kdbcx.cn
http://Yk9nqTxK.kdbcx.cn
http://IShZaOlA.kdbcx.cn
http://HTghIYTP.kdbcx.cn
http://Izv3aNHK.kdbcx.cn
http://aQLoYxht.kdbcx.cn
http://L3tWoLQ4.kdbcx.cn
http://i7ViEo6U.kdbcx.cn
http://wVAKMm2O.kdbcx.cn
http://GHTveobh.kdbcx.cn
http://5YWLHAd6.kdbcx.cn
http://zDBT5ppI.kdbcx.cn
http://wfH1BAuF.kdbcx.cn
http://TKwNFLCQ.kdbcx.cn
http://IpAqwN2y.kdbcx.cn
http://HKeYcuwl.kdbcx.cn
http://90OaooQG.kdbcx.cn
http://LChnK9WY.kdbcx.cn
http://nqiICmlc.kdbcx.cn
http://kplqhpy9.kdbcx.cn
http://2qf06IZj.kdbcx.cn
http://TPUadZp8.kdbcx.cn
http://X4mJGPBc.kdbcx.cn
http://SQ5LBksc.kdbcx.cn
http://DLZ8PYKE.kdbcx.cn
http://bD3za0gx.kdbcx.cn
http://jKZtlIW3.kdbcx.cn
http://eH7ZTooM.kdbcx.cn
http://www.dtcms.com/a/367579.html

相关文章:

  • 竞业限制补偿金怎么算?一次性支付要交税吗?人事系统帮你理清这些坑!
  • 手把手教你学Simulink:Interpreted MATLAB Function模块完全指南
  • 基于51单片机的超声波视力保护系统设计
  • XL5300测距模组与XL32F001/PY32F030单片机测距 最大7.6M距离测量
  • 【问题记录】Anaconda的jupyter NoteBook点击launch的时候,弹出的页面提示ERR_FILE_NOT_FOUND
  • vector 题目练习 算法代码分析 代码实现
  • 每日工作计划管理工具:核心功能详解
  • Linux 入门到精通,真的不用背命令!零基础小白靠「场景化学习法」,3 个月拿下运维 offer,第二十六天
  • 【VLMs篇】05: MiniCPM-V 4.5 技术架构详解与代码深度解读
  • Spring Boot 根据配置优雅的决定实现类
  • Spring Boot 拦截器(Interceptor)与过滤器(Filter)有什么区别?
  • 揭秘“强关联”世界的隐形力量:科学家首次实现对复杂材料的“化学级”精确模拟
  • 个股场外期权行权期限有哪些规定?
  • fpga iic协议
  • 关于嵌入式学习——嵌入式硬件3
  • Function Call实战:用GPT-4调用天气API,实现实时信息查询
  • 2025年热门视频转文字工具测评,助你快速把视频转成文字稿!
  • 基于SpringBoot的家政保洁预约系统【2026最新】
  • C语言中calloc函数
  • flowable基础入门
  • PDF24 Creator:免费的多功能PDF工具
  • 数据可视化大屏精选开源项目
  • rh134第二章复习总结
  • 搭建机器学习模型的数据管道架构方案
  • 富士施乐DocuCentre S2110故障代码01
  • 机器学习 - 使用 ID3 算法从原理到实际举例理解决策树
  • 智能家居芯片:技术核心与创新突破
  • (D题|矿井突水水流漫延模型与逃生方案)2025年高教杯全国大学生数学建模国赛解题思路|完整代码论文集合
  • C#之LINQ
  • [bat-cli] docs | 控制器