使用RDC调用os.startfile()

0 投票
1 回答
923 浏览
提问于 2025-04-18 14:32

我在我的Windows电脑上运行了一个cherrypy服务器。这个服务器负责处理打开文件的请求,文件会在默认的编辑器中打开。(请求中只包含文件路径)

当两个用户通过远程桌面(RDC)登录到同一台Windows服务器时,如果第二个用户发出打开文件的请求,cherrypy会在第一个用户的桌面上打开文件(因为cherrypy服务器是由第一个用户启动的)

有没有什么解决办法?我能否在调用os.startfile()时附带用户信息,这样文件就能在第二个用户的桌面上打开?

1 个回答

1

简单来说,就是:不太容易。

根据os.startfile的说明,它实际上是在调用ShellExecute,而这个功能是没有的。

不过,你可以很简单地让每个用户在自己想要的会话中,启动自己的一份网页服务器。这样的话,大家就得用不同的端口号(或者在登录时随机分配端口号,然后你得以某种方式显示出来),但这也不是太糟糕。


首先,你需要直接与Win32 API进行交互(最好通过pywin32,但如果你真的想用ctypes也可以)。

接下来,一个用户可能已经连接到你的网页服务器,但并没有连接到RDC服务器,或者更糟糕的是,可能有三个不同的RDC会话。那么,“第二个用户的桌面”到底是什么意思呢?如果可以随便选一个,且如果没有就失败,那这个答案是合理的。这部分其实挺简单的:你可以使用Windows终端服务器API(现在是远程桌面服务的一部分,但大多数功能仍以WTS开头)来列出会话,并找到第一个WTS_SESSION_INFO_1与用户匹配的会话。

现在,你只需要获取该用户在该会话中的访问令牌或模拟令牌,这样你就可以调用CreateProcessAsUserCreateProcessWithToken。 (你不能使用CreateProcessWithLogon,因为那样会在他们的RDS会话之外创建一个新会话,这样就没什么用处了。)

那么,如何获取这些东西呢?在这里,你有两个选择:一个是如果你不小心并且不太懂的话,可能会有一个巨大的安全漏洞;另一个也是如此。

如果你不在乎你的终端服务器被黑客攻击,你可以以LocalSystem身份运行你的服务器(或者希望是一个最小的辅助工具,供你的服务器使用),然后调用WTSQueryUserToken。这个其实很简单,只要读到这句话,你的电脑就可能成为某个垃圾邮件机器人网络的一部分。

如果你不在乎用户的账户被黑客攻击,你可以通过你的网页服务器传递他们的凭证,这样你就可以登录并使用ImpersonateLoggedOnUser来获取用户令牌。虽然有办法可以在不明文传输密码的情况下做到这一点,但这并不重要。因为下一步是创建一个新的会话,连接到用户的现有会话,而要从外部做到这一点,你仍然需要他的用户名和密码,尽管你已经以他的身份登录了。总之,完成这些后,你只需在新会话中运行应用程序,他就能在自己的现有会话中看到它,大家都过得很开心,尤其是那个刚刚发现你的朋友在PayPal上用的密码和你服务器上是一样的人,他因此花了17000美元。

如果这些没有吓到你,可以在一个不连接互联网的局域网中创建一些虚拟机,开始玩这些东西——这非常有趣,你会学到很多东西,理想情况下,你能写出满足你需求的东西,并最终让自己相信你没有泄露令牌,准备好部署它。

撰写回答