• shellcode 中 null byte 的成因和避免方式总结


    背景

    shellcode 中要避免 null byte(\x00)这个是个通用的概念(windows,linux 都是一样),因为栈溢出的数据作为字符串写入到栈上,\x00 会作为字符串终止符,毁掉整个 shellcode。

    这就是为什么无论什么类型的栈溢出,无论用到什么技巧,在开发过程中都要千方百计避免 null byte 的出现。当然,还有应用自身的坏字符检测,这个我们以后再讨论,自己写 shellcode 的好处就是能够规避已知的坏字符。在某些特殊情况下,还能节省很多的栈空间(如果栈空间并不大的话,这就是好消息)。

    今天我们讨论下 null byte 的成因,以及几个自己写 shellcode 的时候避免 null byte 的小技巧。

    Null Byte 成因

    开发的过程中,产生 Null Byte 的原因基本上有三个。

    写入寄存器的值过小

    例如我们需要寻找一个栈上的地址作为 Win32 API 的返回值写入地址,这个地址我们选择在 esp-0x260 的位置上。如果直接在作为减数的寄存器中写入 0x260,就会产生 null byte。

    mov eax, esp
    mov ecx, x260
    sub eax, ecx
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    指令本身产生的 Null Byte

    例如 mov eax, [eax] 指令,就会产生 null byte。

    在这里插入图片描述

    说完了两个最基本的成因,我们分享一下避免 null byte 的小技巧。

    call 和 jmp 指令产生的 Null Byte

    这个部分有机会写到自定义 shellcode 话再深入说。由于汇编也是从上到下执行的,这就涉及到代码逻辑的调整以及 call 指令的地址性质,得花点篇幅好好说。

    避免 Null Byte(前两个成因)

    解决小数产生的 Null Byte

    方法1

    针对第一种成因,我们可以选择使用负数的方式来解决。
    拿上面的例子来说,我们可以取 0x260 的负数值,得到

    fffffda0
    
    • 1

    在这里插入图片描述

    然后使用加法而不是减法,得到相同的结果。

    在这里插入图片描述

    所有的数值过小的成因,都可以用这种方法解决。

    方法2

    或者,也可以使用 neg 指令,更加方便。

    ; 先将 0x260 的负数值写入 ecx,然后取负
    mov ecx, 0xfffffda0
    neg ecx
    
    • 1
    • 2
    • 3

    可以看到 opcode 里面没有 null byte。

    在这里插入图片描述

    同时运行起来,寄存器中也是我们想要的值。

    在这里插入图片描述

    在这里插入图片描述

    解决指令本身产生的 Null Byte

    针对第二种成因,很简单了,就是换个寄存器 😄

    在这里插入图片描述

    总结

    第一种避免 null byte 的方式其实很简单,开发过程中注意就行,有小数都换成大数加负数或者负数取负即可。

    第二种避免 null byte 的方式得结合实际情况,看当时哪个寄存器可用。可以看到除了特定的 mov eax, [eax] 会产生 null byte 外,使用其他寄存器都是安全的。

    在这里插入图片描述

    call 和 jmp 指令产生的 Null Byte,得从头开始讲了。不随便挖坑,还有坑没填完 😄

    KEEP CALM AND HACK AWAY!

  • 相关阅读:
    vue 概述
    最小生成树prim算法
    C语言 力扣习题 10.19日 day1
    构建RAG应用-Datawhale笔记
    深度学习阿丘科技AIDI标注工具使用(2.3版本)
    Spring Boot
    A*搜索算法Java实现
    建站系列(一)--- 网站基本常识
    Java8 函数式编程stream流
    Redis——Java客户端配置
  • 原文地址:https://blog.csdn.net/heisejiuhuche/article/details/127894460