V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
dgzting
V2EX  ›  Python

请教各位大佬,如何利用 Python 修改远端 windows 主机的本地账号密码?

  •  
  •   dgzting · 2023-12-04 21:04:01 +08:00 · 1865 次点击
    这是一个创建于 384 天前的主题,其中的信息可能已经有所发展或是发生改变。

    找了一圈,只找到这种命令行方式修改,wmi 连接太慢,不知各位大佬有无其他更好方法可以提供参考,希望无需变更远端 Windows 主机的方法。

    conn=wmi.WMI("x.x.x.x",user="administrator",password="123456")
    conn.Win32_Process.Create("net user administrator 654321") 
    
    14 条回复    2023-12-05 14:37:51 +08:00
    GeekGao
        1
    GeekGao  
       2023-12-04 22:09:09 +08:00
    dgzting
        2
    dgzting  
    OP
       2023-12-04 22:36:00 +08:00 via Android
    @GeekGao winrm 需要在远端 windows 开启服务,操作系统默认没开启
    hxy100
        3
    hxy100  
       2023-12-04 22:56:23 +08:00
    貌似没有更好的办法,不用 WinRM 这类微软自带的原生远程支持模块,只能是自己写一个服务端驻守的服务(或进程),通过向这个服务发送指令来达到目的了,比如我喜欢在手里边为数不多的 Windows 服务器上安装 Cygwin sshd ,通过 Linux ssh 那一套方式来执行一些命令,当然,修改密码也 OK 。
    mingl0280
        4
    mingl0280  
       2023-12-05 01:03:18 +08:00
    很简单啊
    net user 命令
    The syntax of this command is:

    NET USER
    [username [password | *] [options]] [/DOMAIN]
    username {password | *} /ADD [options] [/DOMAIN]
    username [/DELETE] [/DOMAIN]
    username [/TIMES:{times | ALL}]
    username [/ACTIVE: {YES | NO}]

    例如,你想设置用户 abcde 的密码
    只需要执行
    net user abcde new_password
    mingl0280
        5
    mingl0280  
       2023-12-05 01:04:08 +08:00
    哦,你想远程进去改,那你最好在远程主机上开服务了。这个没法避免的。
    geelaw
        6
    geelaw  
       2023-12-05 02:07:50 +08:00 via iPhone   ❤️ 1
    用 net user 修改密码是有多想不开……

    凡是不需要旧密码就可以强行修改密码的手段,都会导致被修改密码用户原先保存的密钥失效,使这个用户(密码学意义上)不能再访问加密数据( EFS 、基于用户的 Crypto 系列 Windows API )。

    推荐从 https://learn.microsoft.com/en-us/windows/win32/api/lmaccess/nf-lmaccess-netuserchangepassword 开始阅读文档。
    louisxxx
        7
    louisxxx  
       2023-12-05 06:20:19 +08:00 via iPhone
    灰鸽子
    ho121
        8
    ho121  
       2023-12-05 07:08:04 +08:00 via Android
    windows 有 sshd 服务的
    mingl0280
        9
    mingl0280  
       2023-12-05 08:47:25 +08:00 via Android
    @geelaw 倒不如说凡是使用不需预先配置的服务,在远程系统上修改任何密码的行为,就是一种后门,不可能给你随便开这种后门的。
    dgzting
        10
    dgzting  
    OP
       2023-12-05 13:58:30 +08:00 via Android
    @geelaw wmi 使用 administrator 连接系统,使用这个账号运行 net user 命令,这种还会有问题吗?就算在计算机管理里面修改密码,也不需要旧密码
    geelaw
        11
    geelaw  
       2023-12-05 14:22:37 +08:00   ❤️ 1
    @dgzting #10 是否有那个问题是数学决定的,不是 API 决定的。Windows 有一些自动加密的内容使用用户的密码导出的密钥,可以简单地理解为这样的模式:

    1. 用户建立的时候生成 AES 密钥 K
    2. 如果用户密码是 P ,则计算 S = MakeKeyFromPassword(P),其中 S 是另一个 AES 密钥
    3. 在硬盘上保存 AutoKey = AES.Enc(key=S, plaintext=K)
    4. 如果用户设置文件 F 要加密,则在硬盘上保存 EncF = AES.Enc(key=K, plaintext=F),解密的时候可以用 P 导出 S ,再用 S 解密 AutoKey 得到 K ,最后用 K 解密 EncF 得到 F

    注意 K 是没有直接保存在硬盘上的。

    5. 如果用户修改密码,那么先用旧密码 P 得到 S ,然后用 S 解密 AutoKey 还原 K ,再用新密码 P' 得到 S',再设置 AutoKey 为 AES.Enc(key=S', plaintext=K),这样每次修改密码的时候只需要重新加密少量数据,不需要把所有文件都解密再重新加密一次。

    这个机制和 Windows 验证用户登录的机制是分开的,你可以认为 Windows 另外保存了密码 P 的 hash 值 H ,而 H 本身没有加密,登录时 Windows 只是计算用户尝试登录时输入的密码的 hash 并和 H 比较。可以简单认为登录成功的时候 Windows 重新见到了 P ,因此可以重新算出 S 、K 并在内存里缓存 P 、S 、K 。然而假设用户没有登录,比如操作系统刚启动的时候,此时 Windows 只知道 H ,不知道 P 、S 、K 。

    如果修改密码的时候提供旧密码,那么 Windows (在操作人有合适的权限的情况下)当然可以修改它记住的 H ,允许用新密码通过 Windows 的登录逻辑。但是没有 P 的时候 S 、K 依然无法还原。

    换言之,是否允许登录纯粹是操作系统想不想的问题,但是否能解密数据,是能不能的问题。

    * * *

    你在 lusrmgr.msc 和 compmgmt.msc 里面修改用户密码的时候会提示

    Resetting this password will might cause irreversible loss of information for this account.

    等等一大串,并且告诉你(作为用户而不是开发者时候)正确做法是按 Ctrl+Alt+Delete 打开“Windows 安全”对话框,选择 Change a Password ,然后输入用户名、旧密码、新密码(两次)。

    net user 和 Set-LocalUser 都不需要旧密码,因此一定会导致密码学数据不再可用(除非你后来想起来旧密码并且旧的例如 AutoKey 和 EncF 还没有被删除,我不知道 Windows 会不会自动删除失效的 AutoKey )。实际上它们和 lusrmgr.msc / compmgmt.msc 归结为同一个 API 。

    而 NetUserChangePassword 需要旧密码,而且实际上 NetUserChangePassword 会类似之前提到的解密、重加密操作,所以不会有这个问题。它和 Ctrl+Alt+Delete 是一样的。

    * * *

    是否丢失密码学保护的数据和用户在本地还是域控制器上无关。在 Windows 提供的 API 下,丢失数据当且仅当修改密码不需要提供旧密码。
    geelaw
        12
    geelaw  
       2023-12-05 14:25:06 +08:00
    @geelaw #11

    >如果修改密码的时候提供旧密码,那么 Windows (在操作人有合适的权限的情况下)当然可以修改它记住的 H ,允许用新密码通过 Windows 的登录逻辑。但是没有 P 的时候 S 、K 依然无法还原。

    应该改成

    >如果修改密码的时候 不 提供旧密码……
    dgzting
        13
    dgzting  
    OP
       2023-12-05 14:36:19 +08:00 via Android
    @geelaw 感谢大佬回答,明白了
    geelaw
        14
    geelaw  
       2023-12-05 14:37:51 +08:00
    Windows 可以创建密码重设磁盘(例如 U 盘;重设密码的时候需要插入此 U 盘,不需要旧密码),我忘记使用密码重设 U 盘是否会导致丢失密码学数据了——理论上可以设计成不会丢失的状态,因为可以把密码学数据备份到 U 盘上,但我不记得具体实现。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2213 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 16:05 · PVG 00:05 · LAX 08:05 · JFK 11:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.