2 个版本
使用旧的 Rust 2015
0.1.2 | 2023 年 3 月 15 日 |
---|---|
0.1.1 | 2022 年 9 月 21 日 |
#1 in #rdp
300KB
5K SLoC
rdp-rs
RUST 中的远程桌面协议
rdp-rs
是 Microsoft 远程桌面协议的纯 Rust 实现。 rdp-rs
随 mstsc-rs
客户端实现一起提供。
此软件包侧重于安全性,面向希望使用安全客户端的用户或想要研究 RDP 的安全研究人员。
为什么?
一方面,远程桌面协议是一个复杂的协议,很难轻松地与之交互。我已经在 Python 和 JavaScript 中实现了 RDP,并使用事件驱动模式。这种模式似乎增加了库的复杂性,最终出现了许多错误,没有 PR,没有人能够深入地玩 RDP。
另一方面,没有开源的 RDP 协议安全实现。
最终,我想要构建一个高度安全、跨平台且高度可定制的客户端。
安装
要在项目中使用 rdp-rs
作为库,请在 Cargo.toml
中添加以下内容:
[dependencies]
rdp-rs = "0.1.0"
您可以通过 cargo 安装二进制文件
cargo install rdp-rs --features=mstsc-rs
mstsc-rs --help
对于 Windows 平台,在 发布 会话中提供了一些预构建的二进制文件。
使用 mstsc-rs
玩
mstsc-rs
是基于 rdp-rs
软件包的 RDP 客户端。它是跨平台且高度可定制的。
mstsc-rs 0.1.0
Sylvain Peyrefitte <citronneur@gmail.com>
Secure Remote Desktop Client in RUST
USAGE:
mstsc-rs.exe [FLAGS] [OPTIONS]
FLAGS:
--admin Restricted admin mode
--auto AutoLogon mode in case of SSL nego
--blank Do not send credentials at the last CredSSP payload
--check Check the target SSL certificate
--ssl Disable Netwoek Level Authentication and only use SSL
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
--dom <domain> Windows domain [default: ]
--hash <hash> NTLM Hash
--height <height> Screen height [default: 600]
--layout <layout> Keyboard layout: us or fr [default: us]
--name <name> Name of the client send to the server [default: mstsc-rs]
--pass <password> Password [default: ]
--port <port> Destination Port [default: 3389]
--target <target> Target IP of the server
--user <username> Username [default: ]
--width <width> Screen width [default: 800]
mstsc-rs
已测试过连接到从 Windows 7 到 Windows 10 运行的服务器。
基本连接(使用 SSL 之上的网络级别身份验证)
默认情况下,mstsc-rs
使用 NLA 作为身份验证协议
mstsc-rs --target IP --user foo --pass bar --dom enterprise
基本连接(使用无 NLA 的 SSL)
您可以使用 ssl
选项禁用 nla,但如果您想使用凭据登录,则需要指定 auto
选项
mstsc-rs --target IP --user foo --pass bar --ssl --auto
传递哈希(使用受限管理员模式)
微软最近为 NLA 身份验证添加了一些新功能。其中之一是受限管理员模式。此模式允许管理员使用 Network
身份验证作为 Interactive
身份验证。此模式允许管理员仅通过其 NTLM 哈希进行身份验证。
mstsc-rs --target IP --user foo --hash a4c37e22527cc1479a8d620d2953b6c0 --admin
检查已登录的用户
在某些情况下,为了进行NLA(网络登录身份验证),使用SSL非常有用。当服务器不强制执行NLA时,使用SSL可以查看哪些用户已连接到服务器,而不会窃取会话。
mstsc-rs --target IP --ssl
当强制执行NLA时,您可以通过使用blank
选项发送空白凭据来检查已打开或可用的会话,通过Interactive
身份验证发送空白凭据。
mstsc-rs --target IP --user foo --pass bar --blank
篡改客户端名称
RDP客户端发送客户端名称。`mstsc-rs
`允许用户自定义它。
mstsc-rs --target IP --user foo --pass bar --name mstsc
将LogonType=10篡改为LogonType=7
当您在一个NLA会话中将blank
选项和auto
选项混合时,这将导致在没有发出4624
的情况下进行登录,使用LogonType=10
,但使用LogonType=7
。
mstsc-rs --target IP --user foo --pass bar --blank --auto
玩转`rdp-rs
`组件
`rdp-rs
`被设计成可以轻松集成到Rust环境中。
如果您想使用常规凭据和NLA进行连接
use std::net::{SocketAddr, TcpStream};
use rdp::core::client::Connector;
use rdp::core::event::{RdpEvent, PointerEvent, PointerButton};
let addr = "192.168.0.1:3389".parse::<SocketAddr>().unwrap();
let tcp = TcpStream::connect(&addr).unwrap();
let mut connector = Connector::new()
.screen(800, 600)
.credentials("domain".to_string(), "username".to_string(), "password".to_string());
let mut client = connector.connect(tcp).unwrap();
现在您想发送一个输入,例如鼠标。
client.write(RdpEvent::Pointer(
// Send a mouse click down at 100x100
PointerEvent {
x: 100 as u16,
y: 100 as u16,
button: PointerButton::Left,
down: true
}
)).unwrap()
现在您想从服务器接收一个事件,例如位图事件。
client.read(|rdp_event| {
match rdp_event {
RdpEvent::Bitmap(bitmap) => {
// do something with bitmap
}
_ => println!("Unhandled event")
}
}).unwrap()
依赖项
~8-19MB
~276K SLoC