在Shellcode中堆栈内存地址

use*_*694 0 stack execve shellcode

我正在阅读一篇关于编写shellcode(使用堆栈方法的execve)的基本文章:http://hackoftheday.securitytube.net/2013/04/demystifying-execve-shellcode-stack.html

在步骤6中:它推送空字符,因为字符串"/ bin/sh"为空终止.之后,它以相反的顺序推送字符串"/ bin/sh"

为什么字符串以相反的顺序被推入堆栈?为什么在将字符串推入堆栈之前"推出"字符串的空字符?

jwa*_*zko 5

应放入堆栈的字符串如下:

//bin/sh + '\0'(null terminator) + alignment(3 additional null characters)  -   gives 3 DWORDs (12 bytes)
Run Code Online (Sandbox Code Playgroud)

为此,我们必须按正确的顺序执行一组指令:

xor     eax, eax        ;zero out full 32 bits of eax register
push    eax             ;0x00000000
push    0x68732f6e      ;hs/n
push    0x69622f2f      ;ib//
Run Code Online (Sandbox Code Playgroud)

为什么要这样的命令?

因为堆栈性质.元素应以相反的顺序放入其中,以便将来正确读出.Stack是一种数据结构,具有先进先出(FILO)排序(与堆相对).这意味着放入堆栈的第一个项目是最后一个项目.随着堆栈大小的变化,它会朝着更低的内存地址向上增长:

                        memory
.---------------.-- 00  <-- top    / low addresses
|       .       |       x+1
|      /|\      |       x+2
|       |       |        .
|     stack     |        .
|grows up toward|        .
|lower addresses|       x+n
'---------------'-- FF  <-- bottom / high addresses
Run Code Online (Sandbox Code Playgroud)

现在,这2个双字呢:0x68732f6e (hs/n)0x69622f2f (ib//)?他们是如何相关的//bin/sh

看看0x68732f6e我们可以看到逐字节显示的字节反转效果,实际存储在内存中,4个字节:0x6e 0x2f 0x73 0x68 (n/sh).它与IA-32架构特定的字节序连接,在手动将字节放入堆栈时必须考虑这一点.在x86处理器上,值以小端(与SPARC处理器上的大端相反)字节顺序存储,这意味着首先存储最低有效字节(小端先到):

byte3 byte2 byte1 byte0
Run Code Online (Sandbox Code Playgroud)

将按如下方式安排在记忆中:

base address+0   byte0
base address+1   byte1
base address+2   byte2
base address+3   byte3
Run Code Online (Sandbox Code Playgroud)

最后,为了可视化内存空间的填充方式,请看下面的内容:

.---------  push    eax             ;0x00000000
|   .-----  push    0x68732f6e      ;hs/n           bytes reversed
|   |   .-  push    0x69622f2f      ;ib//           bytes reversed 
|   |   |                                       
|   |   |      register                     
|   |   '>  |69|62|2f|2f| (ib//)      memory
|   |        |  |  |  |                 ..  
|   |        |  |  |  '------->     x:  2f  '/'
|   |        |  |  '---------->   x+1:  2f  '/'
|   |        |  '------------->   x+2:  62  'b'
|   |        '---------------->   x+3:  69  'i'
|   |          little endian    
|   |                   
|   '---->  |68|73|2f|6e| (hs/n)      
|            |  |  |  | 
|            |  |  |  '------->   x+4:  6e  'n'
|            |  |  '---------->   x+5:  2f  '/'
|            |  '------------->   x+6:  73  's'
|            '---------------->   x+7:  68  'h'
|
'-------->  |00|00|00|00| (\0\0\0\0)
             |  |  |  |                 
             |  |  |  '------->   x+8:  00  '\0'
             |  |  '---------->   x+9:  00  '\0'
             |  '------------->   x+10: 00  '\0'
             '---------------->   x+11: 00  '\0'
                                        ..
Run Code Online (Sandbox Code Playgroud)

你可以使用gdb来检查它:

(gdb) x/12b $sp
0xbfb530b0:     0x2f    0x2f    0x62    0x69    0x6e    0x2f    0x73    0x68
0xbfb530b8:     0x00    0x00    0x00    0x00
(gdb) x/12c $sp
0xbfb530b0:     47 '/'  47 '/'  98 'b'  105 'i' 110 'n' 47 '/'  115 's' 104 'h'
0xbfb530b8:     0 '\0'  0 '\0'  0 '\0'  0 '\0'
(gdb) x/3w $sp
0xbfb530b0:     0x69622f2f      0x68732f6e      0x00000000
Run Code Online (Sandbox Code Playgroud)