组装 - 使用 push 和 ESP-Register 来存储地址

逆向工程 部件 特别是 登记
2021-06-22 02:38:14

我在教程中发现了以下装配线,但我不明白:

 xor eax, eax      => clear, I know that, it makes eax = 0
 push eax          => push 0 on the stack
 push 0x68732f2f   => push "//sh" to the stack (the numbers are opcodes I guess, output of hexdump)
 push 0x6e69622f   => push "/bin" to the stack (again opcodes, representing "/bin" )
 mov ebx, esp      => put address of "/bin//sh\0" into ebx, via esp
 ....

我的问题: 为什么我们通过 esp 使用 mov ebx, esp 行将“/bin//sh”的地址放入 ebx 中?

我画个草图:

         |                        |
         |------------------------|<-----ESP (I know that ESP always points to the top)
(a)      |  0x6e69622f  ("//sh")  |
         |------------------------|
(b)      |   0x68732f2f ("/bin")  |
         |------------------------|
(c)      |       0                |
         |------------------------|

我如何尝试向自己解释(我不确定它是否正确,但我想在我在这里的论坛上提问之前想了一下):

ESP 是一个 32 位寄存器,因此它足够大以包含 (a)、(b) 和 (c)(我在上面标记的)处的地址。

是对的吗?我希望有人可以帮助我?

最好的祝福,

2个回答

首先,让我澄清一下:

ESP是一个 32 位寄存器,它包含一个指向堆栈的指针。无论如何,它都不够大comprise the addresses at [...]这仅仅是指向在其中保留存储位置abc


你的漏洞利用所做的是将一个字符串推入堆栈。/bin//sh十六进制表示:

2f 62 69 6e 2f 2f 73 68

现在看看你的程序集:

push 0x68732f2f
push 0x6e69622f

不是任何类型的操作码,而是字符串的 ASCII 表示,作为双字推送(基本上,以更少的指令推送字符串)

另一种方法是:

push '/' ; same as push 0x2f
push 'b' ; same as push 0x62
push 'i' ; same as push 0x69
push 'n' ; same as push 0x6e
push '/' ; same as push 0x2f
push '/' ; same as push 0x2f
push 's' ; same as push 0x73
push 'h' ; same as push 0x68

基本上,它的作用与上述相同,只是指令更少,通过将 ASCII 代码组合在一起:6e69622f而不是2f, 62, 69,6e分隔。它还推送 a 0,它是C 样式 string终止符,以便字符串在那里结束。

现在,堆栈有/bin//sh,而你要做的就是调用sys_execve,通过做int 0x80(中断),这是Linux的使用,使系统调用的方式。

由于对于系统调用IDsys_execve是11,您移动11al(下部eax),并把第一个参数到ebx,这是一个指针,指向一个字符串由于ESP指向栈顶,并且栈顶包含/bin//sh我们之前推送的内容,因此漏洞利用程序集意味着:

sys_execve("/bin//sh");

就这样,被剥削了!:)

它只是一种在漏洞利用中嵌入字符串的技术,因为您可以以常规方式定义它们,因为您需要它们的地址来访问它们,但在漏洞利用中,这些地址是动态的,而不是静态的或常量。