HP_imc 5.1_E0202 imf.dll recv packets integer overflow

imf.dll
版本 HP_iMC_PLAT_5.1_E0202_Standard_Windows_HP_iMC_PLAT_5.1_E0202_Standard_Windows
漏洞彙編代碼:
.text:003B4083                 mov     ecx, [esi+38h]
.text:003B4086                 mov     eax, [ecx+ebp+18h] ; ECX tainted buffer
.text:003B408A                 movzx   edx, word ptr [ecx+ebp+16h]
.text:003B408F                 add     ecx, ebp
.text:003B4091                 movzx   ecx, byte ptr [ecx+1Bh]
.text:003B4095                 mov     edi, eax
.text:003B4097                 mov     ebx, eax
.text:003B4099                 shl     edi, 10h
.text:003B409C                 shr     eax, 8
.text:003B409F                 and     ebx, 0FF00h
.text:003B40A5                 or      edi, ebx
.text:003B40A7                 and     eax, 0FF00h
.text:003B40AC                 shl     edi, 8
.text:003B40AF                 or      edi, eax
.text:003B40B1                 movzx   eax, dl
.text:003B40B4                 shl     eax, 8
.text:003B40B7                 shr     edx, 8
.text:003B40BA                 or      edi, ecx
.text:003B40BC                 or      eax, edx
.text:003B40BE                 add     edi, eax
.text:003B40C0                 push    edi
.text:003B40C1                 push    1Ch
.text:003B40C3                 call    ??2CImfMsgPdu@@SAPAXII@Z ; CImfMsgPdu::operator new(uint,uint)
.text:003B40C8                 add     esp, 8
.text:003B40CB                 xor     ebx, ebx
.text:003B40CD                 mov     [esi+30h], eax
.text:003B40D0                 mov     [esi+40h], edi..
..
.text:003B6870 ??2CImfMsgPdu@@SAPAXII@Z proc near      ; CODE XREF: CImfAppMgr::handleEvents(void)+10Ap
.text:003B6870                                         ; CImfAppMgr::subscribe(ulong,CImfMsgPdu::EnumImfPduType,uchar,ushort)+75p ...
.text:003B6870
.text:003B6870 arg_4           = dword ptr  8
.text:003B6870
.text:003B6870                 mov     eax, [esp+arg_4]
.text:003B6874                 add     eax, 4
.text:003B6877                 push    eax
.text:003B6878                 push    0
.text:003B687A                 push    40h
.text:003B687C                 push    100h
.text:003B6881                 call    ?instance@CImfMemMan@@SAPAV1@III@Z ; CImfMemMan::instance(uint,uint,uint)
.text:003B6886                 add     esp, 0Ch
.text:003B6889                 mov     ecx, eax
.text:003B688B                 call    ?allocMem@CImfMemMan@@QAEPAXI@Z ; CImfMemMan::allocMem(uint)
.text:003B6890                 test    eax, eax
.text:003B6892                 jnz     short loc_3B6895
.text:003B6894                 retn
.text:003B6895 ; ---------------------------------------------------------------------------
.text:003B6895
.text:003B6895 loc_3B6895:                             ; CODE XREF: CImfMsgPdu::operator new(uint,uint)+22j
.text:003B6895                 add     eax, 4
.text:003B6898                 retn
.text:003B6898 ??2CImfMsgPdu@@SAPAXII@Z endp

do
  {
    if ( v3 ^ v4 )
    {
      ACE_OS__sprintf(&v13, "receive() return %d, error in network connection.", bResult);
      CImfRunLog__info(&v13);
      v15 = -1;
      CImfDebugInfo___CImfDebugInfo(&v12);
      return sub_3C19FC();
    }
    v6 = bResult + v2->recvsize == 0;
    v2->recvsize += bResult;
    v7 = v1;
    if ( v6 )
      goto LABEL_11;
    while ( 1 )
    {
      if ( v2->MsgPdu_Buffer != v1 )
        goto LABEL_9;
      if ( (unsigned int)(v2->recvsize - v7) < 0x1C )
        break;
      v8 = v2->recvbuffer;                      // 計算一個buffersize
      v9 = (((unsigned int)*(_WORD *)(v7 + 22 + v8) >> 8) | ((unsigned __int8)*(_WORD *)(v7 + 22 + v8) << 8))
         + (*(_BYTE *)(v7 + 27 + v8) | (*(_DWORD *)(v7 + 24 + v8) >> 8) & 0xFF00 | ((*(_DWORD *)(v7 + 24 + v8) & 0xFF00 | (*(_DWORD *)(v7 + 24 + v8) << 16)) << 8));
      v1 = 0;
      v2->MsgPdu_Buffer = CImfMsgPdu__operator new(0x1Cu, v9);
      v2->MsgPdu_Buffersize = v9;
      v2->MsgPdu_BufferOffset = 0;
LABEL_9:
      if ( (unsigned int)(v2->recvsize - v7) < v2->MsgPdu_Buffersize )
      {
        memcpy(
          (void *)(v2->MsgPdu_Buffer + v2->MsgPdu_BufferOffset),
          (const void *)(v7 + v2->recvbuffer),
          v2->recvsize - v7);
        v10 = v2->recvsize;
        v2->MsgPdu_BufferOffset += v2->recvsize - v7;
        v2->MsgPdu_Buffersize += v7 - v10;
        v2->recvsize = v1;
        goto LABEL_12;
      }
      memcpy(
        (void *)(v2->MsgPdu_Buffer + v2->MsgPdu_BufferOffset),
        (const void *)(v7 + v2->recvbuffer),
        v2->MsgPdu_Buffersize);
      sub_3A6EC0(v2->MsgPdu_Buffer);
      sub_3B2D60((void *)v2->MsgPdu_Buffer);
      v7 += v2->MsgPdu_Buffersize;
      v2->MsgPdu_Buffer = v1;
      v2->MsgPdu_BufferOffset = v1;
      v2->MsgPdu_Buffersize = v1;
      if ( v2->recvsize == v7 )
        goto LABEL_11;
    }
    if ( v7 != v1 )
    {
      memmove((void *)v2->recvbuffer, (const void *)(v2->recvbuffer + v7), v2->recvsize - v7);
      v2->recvsize -= v7;
      v7 = 0;
    }
LABEL_11:
    if ( v2->recvsize == v7 )
LABEL_12:
      v2->recvsize = v1;
    bResult = CImfConnTask__receive(v2, v2->recvsize + v2->recvbuffer, recv_max_size - v2->recvsize);
    v4 = __SETO__(bResult, v1);
    v3 = bResult - v1 < 0;
  }
  while ( bResult != v1 );


例如這樣的buffer
41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 
51 52 53 54 55 56 CE CD FF FF 31 32 33 34 35 36
37 38 39

offse+0x16  CECDFFFF3132

即可滿足漏洞觸發條件


這個漏洞在服務端接受的地方已經補了,但是所有客戶端接收數據包的地方仍然存在。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章