【国内某组态软件和plc的通信漏洞挖掘】

news2024/11/24 0:28:59

因为已从原单位离职,复现的环境也已经丢失,再加上也没怎么提交过漏洞,导致上传cnvd失败,故发在此处,万一有用的话,有缘人可自行提交漏洞库。
在这里插入图片描述

(一) 环境
组态软件IP地址:192.168.0.189
PLC IP:192.168.0.70
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8FL7yrRJ-1684205261865)(upload/tmp/653410_PCTNTV9SMB2BUFH.png)]

(二) 原理
组态软件MaView中有一个进程windowsRTE.exe,它在udp端口20181(也有可能是20281端口,忘记了)监听,并与plc通信和交互数据:

通过调试,发现该端口的数据包头格式可以定义如下:

typedef struct
{
	USHORT Version;		        //0
	UCHAR CmdType;		        //2
	UCHAR PkgSeq;			//3
	DWORD unused;			//4
	ULONGLONG CycleID;	        //8
	UINT BeatCount;		        //16
	USHORT PkgID;			//20
	USHORT PkgCount;		//22
	UINT PkgBodyLen;		//24
}UDPPRESLAYERHEAD;

通过跟踪WindowsRTE.exe模块中的函数0x0048C27B(UdpRecv),发现数据包字段的处理存在逻辑漏洞,拷贝时有可能导致缓冲区溢出。

0x0048C27B函数详细代码如下:

INT __cdecl UdpRecv(INT servSocket, char *recvBuff)
{
  INT result; // eax@2
  char *v3; // eax@11
  char *v4; // eax@11
  INT v5; // ebx@11
  char *v6; // eax@11
  INT v7; // ebx@11
  char *v8; // eax@11
  int v9; // edx@19
  int v10; // edx@28
  int v11; // edx@37
  int v12; // edx@48
  int v13; // edx@57
  int v14; // edx@66
  int v15; // edx@75
  CHAR cfgIP[16]; // [sp+3Bh] [bp-11Dh]@11
  CHAR recvIP[16]; // [sp+4Bh] [bp-10Dh]@11
  UCHAR iosrIPCount; // [sp+5Bh] [bp-FDh]@6
  SOCKADDR_IN cfgClntSocketAddr; // [sp+5Ch] [bp-FCh]@11
  INT recvClntSockAddrSize; // [sp+6Ch] [bp-ECh]@1
  SOCKADDR_IN recvClntSocketAddr; // [sp+70h] [bp-E8h]@3
  INT err; // [sp+80h] [bp-D8h]@99
  UINT pkgBodyLen; // [sp+84h] [bp-D4h]@19
  _DWORD cycleID[3]; // [sp+88h] [bp-D0h]@19
  UCHAR pkgSeq; // [sp+95h] [bp-C3h]@19
  USHORT pkgID; // [sp+96h] [bp-C2h]@19
  USHORT pkgCount; // [sp+98h] [bp-C0h]@19
  USHORT version; // [sp+9Ah] [bp-BEh]@19
  UINT pkgBodyLen_0; // [sp+9Ch] [bp-BCh]@28
  _DWORD cycleID_0[3]; // [sp+A0h] [bp-B8h]@28
  UCHAR pkgSeq_0; // [sp+ADh] [bp-ABh]@28
  USHORT pkgID_0; // [sp+AEh] [bp-AAh]@28
  USHORT pkgCount_0; // [sp+B0h] [bp-A8h]@28
  USHORT version_0; // [sp+B2h] [bp-A6h]@28
  UINT pkgBodyLen_1; // [sp+B4h] [bp-A4h]@37
  _DWORD cycleID_1[3]; // [sp+B8h] [bp-A0h]@37
  UCHAR pkgSeq_1; // [sp+C5h] [bp-93h]@37
  USHORT pkgID_1; // [sp+C6h] [bp-92h]@37
  USHORT pkgCount_1; // [sp+C8h] [bp-90h]@37
  USHORT version_1; // [sp+CAh] [bp-8Eh]@37
  UINT pkgBodyLen_2; // [sp+CCh] [bp-8Ch]@48
  _DWORD cycleID_2[3]; // [sp+D0h] [bp-88h]@48
  UCHAR pkgSeq_2; // [sp+DDh] [bp-7Bh]@48
  USHORT pkgID_2; // [sp+DEh] [bp-7Ah]@48
  USHORT pkgCount_2; // [sp+E0h] [bp-78h]@48
  USHORT version_2; // [sp+E2h] [bp-76h]@48
  UINT pkgBodyLen_3; // [sp+E4h] [bp-74h]@57
  _DWORD cycleID_3[3]; // [sp+E8h] [bp-70h]@57
  UCHAR pkgSeq_3; // [sp+F5h] [bp-63h]@57
  USHORT pkgID_3; // [sp+F6h] [bp-62h]@57
  USHORT pkgCount_3; // [sp+F8h] [bp-60h]@57
  USHORT version_3; // [sp+FAh] [bp-5Eh]@57
  UINT pkgBodyLen_4; // [sp+FCh] [bp-5Ch]@66
  _DWORD cycleID_4[3]; // [sp+100h] [bp-58h]@66
  UCHAR pkgSeq_4; // [sp+10Dh] [bp-4Bh]@66
  USHORT pkgID_4; // [sp+10Eh] [bp-4Ah]@66
  USHORT pkgCount_4; // [sp+110h] [bp-48h]@66
  USHORT version_4; // [sp+112h] [bp-46h]@66
  UINT pkgBodyLen_5; // [sp+114h] [bp-44h]@75
  _DWORD cycleID_5[3]; // [sp+118h] [bp-40h]@75
  UCHAR pkgSeq_5; // [sp+127h] [bp-31h]@75
  USHORT pkgID_5; // [sp+128h] [bp-30h]@75
  USHORT pkgCount_5; // [sp+12Ah] [bp-2Eh]@75
  USHORT version_5; // [sp+12Ch] [bp-2Ch]@75
  UCHAR cmdType; // [sp+12Fh] [bp-29h]@18
  UDP_PRESLAYER_HEAD *udpPresLayerHead; // [sp+130h] [bp-28h]@18
  INT recvIpLen; // [sp+134h] [bp-24h]@10
  INT cfgIpLen; // [sp+138h] [bp-20h]@10
  INT clntIP; // [sp+13Ch] [bp-1Ch]@10
  INT i; // [sp+140h] [bp-18h]@1
  INT iRead; // [sp+144h] [bp-14h]@1
  INT isIPExist; // [sp+148h] [bp-10h]@10
  INT ii; // [sp+14Ch] [bp-Ch]@10

  iRead = -1;
  i = 0;
  recvClntSockAddrSize = 16;
  if ( iosrvServSock == -1 )
  {
    KyldLog(1, 3, "UdpRecv:servSocket  is not ctreated.\n");
    result = 2;
  }
  else
  {
    memset(iosrvRecvBuff, 0, 0x514u);
    iRead = recvfrom(
              iosrvServSock,
              iosrvRecvBuff,
              1300,
              0,
              (struct sockaddr *)&recvClntSocketAddr,
              &recvClntSockAddrSize);
    if ( iRead <= 0 )
    {
LABEL_98:
      if ( iRead >= 0 )
      {
        if ( iRead )
        {
          result = 1;
        }
        else
        {
          KyldLog(1, 3, "UdpRecv:ERROR!!! ioser disconnect ,or network disconnect\n");
          IosrComVarInit();
          SetIosrComStatus(-1);
          result = 1;
        }
      }
      else
      {
        err = GetLastError();
        if ( err != 4 && err != 140 && err != 10035 )
        {
          if ( err == 10054 )
            KyldLog(
              1,
              3,
              "UdpRecv: ERROR!!! ioserver disconnect abnormally,remote close forcibly .:iRead=%d,errno=%d\n",
              iRead,
              10054);
          else
            KyldLog(1, 3, "UdpRecv: read ERROR!!!:iRead=%d,errno=%d\n", iRead, err);
          IosrComVarInit();
          SetIosrComStatus(-1);
          result = 2;
        }
        else
        {
          result = 1;
        }
      }
    }
    else
    {
      iosrvClntAddr = recvClntSocketAddr;
      iosrvClntAddrSize = recvClntSockAddrSize;
      isRecvTimerActived = 1;
      recvTimeOut = 10000;
      SetIosrComStatus(0);
      if ( recvBuff )
      {
        iosrIPCount = 0;
        memset(gIosrIpSets, 0, 0x190u);
        if ( IO_GetIOSvrNetIp(gIosrIpSets, &iosrIPCount) )
        {
          KyldLog(1, 3, "UdpRecv:IO_GetIOSvrNetIp fail,ioser can not communicate.\n");
          result = 2;
        }
        else if ( iosrIPCount )
        {
          isIPExist = 0;
          clntIP = 0;
          cfgIpLen = 0;
          recvIpLen = 0;
          for ( ii = 0; ii < iosrIPCount; ++ii )
          {
            memset(recvIP, 0, 0x10u);
            memset(cfgIP, 0, 0x10u);
            cfgClntSocketAddr.sin_addr.S_un.S_addr = gIosrIpSets[ii];
            v3 = inet_ntoa(cfgClntSocketAddr.sin_addr);
            cfgIpLen = strlen(v3);
            v4 = inet_ntoa(recvClntSocketAddr.sin_addr);
            recvIpLen = strlen(v4);
            v5 = recvIpLen;
            v6 = inet_ntoa(recvClntSocketAddr.sin_addr);
            memcpy(recvIP, v6, v5);
            v7 = cfgIpLen;
            v8 = inet_ntoa(cfgClntSocketAddr.sin_addr);
            memcpy(cfgIP, v8, v7);
            KyldLog(
              1,
              1,
              "UdpRecv:IO_GetIOSvrNetIp success,iosrIPCount=%d,i=%d,recvIP=%s,cfgIP=%s,cfgIpLen=%d,recvIPLen=%d.\n",
              iosrIPCount,
              ii,
              recvIP,
              cfgIP,
              cfgIpLen,
              recvIpLen);
            if ( !strncmp(recvIP, cfgIP, cfgIpLen) && cfgIpLen == recvIpLen )
            {
              isIPExist = 1;
              break;
            }
          }
          if ( isIPExist == 1 )
          {
            KyldLog(1, 1, "UdpRecv:IO_GetIOSvrNetIp,ip(%s) is legal,communication normal.\n", recvIP);
            udpPresLayerHead = (UDP_PRESLAYER_HEAD *)iosrvRecvBuff;
            cmdType = iosrvRecvBuff[2];
            switch ( cmdType )
            {
              case 1u:
                version = udpPresLayerHead->Version;
                pkgCount = udpPresLayerHead->PkgCount;
                pkgID = udpPresLayerHead->PkgID;
                pkgSeq = udpPresLayerHead->PkgSeq;
                v9 = HIDWORD(udpPresLayerHead->CycleID);
                cycleID[0] = udpPresLayerHead->CycleID;
                cycleID[1] = v9;
                pkgBodyLen = udpPresLayerHead->PkgBodyLen;
                if ( pkgBodyLen <= 0x400 )
                {
                  if ( pkgCount )
                  {
                    memcpy(&iosrvDiagRequestTable + 1024 * (pkgID - 1), &iosrvRecvBuff[32], pkgBodyLen);
                    if ( ++diagRequestPkgCount == 1 )
                    {
                      isDiagRequestTimerActived = 1;
                      diagRequestTimeOut = 100;
                    }
                    if ( pkgCount != diagRequestPkgCount )
                      goto LABEL_84;
                    KyldLog(1, 1, "UdpRecv:ioserver recv diag request.\n");
                    diagRequestPkgCount = 0;
                    isDiagRequestTimerActived = 0;
                    diagRequestTimeOut = 100;
                    result = 32;
                  }
                  else
                  {
                    KyldLog(1, 3, "UdpRecv:CmdIosrDiagRequest,ERROR!!!pkgCount<=0,pkgCount=%d\n", 0);
                    result = 2;
                  }
                }
                else
                {
                  KyldLog(
                    1,
                    3,
                    "UdpRecv:CmdIosrDiagRequest,ERROR!!!pkgBodyLen > SUB_PKG_SIZE_MAX,pkgBodyLen=%d\n",
                    pkgBodyLen);
                  result = 2;
                }
                break;
              case 3u:
                if ( GetStateMorS() != 1 )
                  goto LABEL_84;
                KyldLog(1, 1, "UdpRecv:CmdIosrDataRequest,line=%d\n", 1591);
                version_0 = udpPresLayerHead->Version;
                pkgCount_0 = udpPresLayerHead->PkgCount;
                pkgID_0 = udpPresLayerHead->PkgID;
                pkgSeq_0 = udpPresLayerHead->PkgSeq;
                v10 = HIDWORD(udpPresLayerHead->CycleID);
                cycleID_0[0] = udpPresLayerHead->CycleID;
                cycleID_0[1] = v10;
                pkgBodyLen_0 = udpPresLayerHead->PkgBodyLen;
                if ( pkgBodyLen_0 <= 0x400 )
                {
                  if ( pkgCount_0 )
                  {
                    memcpy(&iosrvDataRequestTable + 1024 * (pkgID_0 - 1), &iosrvRecvBuff[32], pkgBodyLen_0);
                    if ( ++dataRequestPkgCount == 1 )
                    {
                      isDataRequestTimerActived = 1;
                      dataRequestTimeOut = 100;
                    }
                    if ( pkgCount_0 != dataRequestPkgCount )
                      goto LABEL_84;
                    KyldLog(1, 1, "UdpRecv:ioserver recv data request.\n");
                    dataRequestPkgCount = 0;
                    isDataRequestTimerActived = 0;
                    dataRequestTimeOut = 100;
                    result = 33;
                  }
                  else
                  {
                    KyldLog(1, 3, "UdpRecv:CmdIosrDataRequest,ERROR!!!pkgCount<=0,pkgCount=%d\n", 0);
                    result = 2;
                  }
                }
                else
                {
                  KyldLog(
                    1,
                    3,
                    "UdpRecv:CmdIosrDataRequest,ERROR!!!pkgBodyLen > SUB_PKG_SIZE_MAX,pkgBodyLen=%d\n",
                    pkgBodyLen_0);
                  result = 2;
                }
                break;
              case 5u:
                if ( GetStateMorS() != 1 )
                  goto LABEL_84;
                KyldLog(1, 1, "UdpRecv:CmdIosrDataResend,line=%d\n", 1640);
                version_1 = udpPresLayerHead->Version;
                pkgCount_1 = udpPresLayerHead->PkgCount;
                pkgID_1 = udpPresLayerHead->PkgID;
                pkgSeq_1 = udpPresLayerHead->PkgSeq;
                v11 = HIDWORD(udpPresLayerHead->CycleID);
                cycleID_1[0] = udpPresLayerHead->CycleID;
                cycleID_1[1] = v11;
                pkgBodyLen_1 = udpPresLayerHead->PkgBodyLen;
                if ( pkgBodyLen_1 <= 0x400 )
                {
                  if ( pkgCount_1 )
                  {
                    memcpy(&iosrvDataResendTable + 1024 * (pkgID_1 - 1), &iosrvRecvBuff[32], pkgBodyLen_1);
                    if ( ++dataResendPkgCount == 1 )
                    {
                      isDataResendTimerActived = 1;
                      dataResendTimeOut = 100;
                    }
                    if ( pkgCount_1 != dataResendPkgCount )
                      goto LABEL_84;
                    dataResendPkgCount = 0;
                    isDataResendTimerActived = 0;
                    dataResendTimeOut = 100;
                    result = 34;
                  }
                  else
                  {
                    KyldLog(1, 3, "UdpRecv:CmdIosrDataResend,ERROR!!!pkgCount<=0,pkgCount=%d\n", 0);
                    result = 2;
                  }
                }
                else
                {
                  KyldLog(
                    1,
                    3,
                    "UdpRecv:CmdIosrDataResend,ERROR!!!pkgBodyLen > SUB_PKG_SIZE_MAX,pkgBodyLen=%d\n",
                    pkgBodyLen_1);
                  result = 2;
                }
                break;
              case 4u:
                if ( GetStateMorS() != 1 )
                  goto LABEL_84;
                result = 39;
                break;
              case 6u:
                if ( GetStateMorS() != 1 )
                  goto LABEL_84;
                KyldLog(1, 1, "UdpRecv:CmdIosrItemRead,line=%d\n", 1702);
                version_2 = udpPresLayerHead->Version;
                pkgCount_2 = udpPresLayerHead->PkgCount;
                pkgID_2 = udpPresLayerHead->PkgID;
                pkgSeq_2 = udpPresLayerHead->PkgSeq;
                v12 = HIDWORD(udpPresLayerHead->CycleID);
                cycleID_2[0] = udpPresLayerHead->CycleID;
                cycleID_2[1] = v12;
                pkgBodyLen_2 = udpPresLayerHead->PkgBodyLen;
                if ( pkgBodyLen_2 <= 0x400 )
                {
                  if ( pkgCount_2 )
                  {
                    memcpy(&iosrvItemReadTable + 1024 * (pkgID_2 - 1), &iosrvRecvBuff[32], pkgBodyLen_2);
                    if ( ++itemReadPkgCount == 1 )
                    {
                      isItemReadTimerActived = 1;
                      itemReadTimeOut = 100;
                    }
                    if ( pkgCount_2 != itemReadPkgCount )
                      goto LABEL_84;
                    itemReadPkgCount = 0;
                    isItemReadTimerActived = 0;
                    itemReadTimeOut = 100;
                    result = 35;
                  }
                  else
                  {
                    KyldLog(1, 3, "UdpRecv:CmdIosrItemRead,ERROR!!!pkgCount<=0,pkgCount=%d\n", 0);
                    result = 2;
                  }
                }
                else
                {
                  KyldLog(
                    1,
                    3,
                    "UdpRecv:CmdIosrItemRead,ERROR!!!pkgBodyLen > SUB_PKG_SIZE_MAX,pkgBodyLen=%d\n",
                    pkgBodyLen_2);
                  result = 2;
                }
                break;
              case 7u:
                if ( GetStateMorS() != 1 )
                  goto LABEL_84;
                KyldLog(1, 1, "UdpRecv:CmdIosrItemWrite,line=%d\n", 1750);
                version_3 = udpPresLayerHead->Version;
                pkgCount_3 = udpPresLayerHead->PkgCount;
                pkgID_3 = udpPresLayerHead->PkgID;
                pkgSeq_3 = udpPresLayerHead->PkgSeq;
                v13 = HIDWORD(udpPresLayerHead->CycleID);
                cycleID_3[0] = udpPresLayerHead->CycleID;
                cycleID_3[1] = v13;
                pkgBodyLen_3 = udpPresLayerHead->PkgBodyLen;
                if ( pkgBodyLen_3 <= 0x400 )
                {
                  if ( pkgCount_3 )
                  {
                    memcpy(&iosrvItemWriteTable + 1024 * (pkgID_3 - 1), &iosrvRecvBuff[32], pkgBodyLen_3);
                    if ( ++itemWritePkgCount == 1 )
                    {
                      isItemWriteTimerActived = 1;
                      itemWriteTimeOut = 100;
                    }
                    if ( pkgCount_3 != itemWritePkgCount )
                      goto LABEL_84;
                    itemWritePkgCount = 0;
                    isItemWriteTimerActived = 0;
                    itemWriteTimeOut = 100;
                    result = 36;
                  }
                  else
                  {
                    KyldLog(1, 3, "UdpRecv:CmdIosrItemWrite,ERROR!!!pkgCount<=0,pkgCount=%d\n", 0);
                    result = 2;
                  }
                }
                else
                {
                  KyldLog(
                    1,
                    3,
                    "UdpRecv:CmdIosrItemWrite,ERROR!!!pkgBodyLen > SUB_PKG_SIZE_MAX,pkgBodyLen=%d\n",
                    pkgBodyLen_3);
                  result = 2;
                }
                break;
              case 8u:
                if ( GetStateMorS() != 1 )
                  goto LABEL_84;
                KyldLog(1, 1, "UdpRecv:CmdIosrItemForce,line=%d\n", 1798);
                version_4 = udpPresLayerHead->Version;
                pkgCount_4 = udpPresLayerHead->PkgCount;
                pkgID_4 = udpPresLayerHead->PkgID;
                pkgSeq_4 = udpPresLayerHead->PkgSeq;
                v14 = HIDWORD(udpPresLayerHead->CycleID);
                cycleID_4[0] = udpPresLayerHead->CycleID;
                cycleID_4[1] = v14;
                pkgBodyLen_4 = udpPresLayerHead->PkgBodyLen;
                if ( pkgBodyLen_4 <= 0x400 )
                {
                  if ( pkgCount_4 )
                  {
                    memcpy(&iosrvItemForceTable + 1024 * (pkgID_4 - 1), &iosrvRecvBuff[32], pkgBodyLen_4);
                    if ( ++itemForcePkgCount == 1 )
                    {
                      isItemForceTimerActived = 1;
                      itemForceTimeOut = 100;
                    }
                    if ( pkgCount_4 != itemForcePkgCount )
                      goto LABEL_84;
                    itemForcePkgCount = 0;
                    isItemForceTimerActived = 0;
                    itemForceTimeOut = 100;
                    result = 37;
                  }
                  else
                  {
                    KyldLog(1, 3, "UdpRecv:CmdIosrItemForce,ERROR!!!pkgCount<=0,pkgCount=%d\n", 0);
                    result = 1;
                  }
                }
                else
                {
                  KyldLog(
                    1,
                    3,
                    "UdpRecv:CmdIosrItemForce,ERROR!!!pkgBodyLen > SUB_PKG_SIZE_MAX,pkgBodyLen=%d\n",
                    pkgBodyLen_4);
                  result = 2;
                }
                break;
              case 9u:
                if ( GetStateMorS() != 1 )
                  goto LABEL_84;
                KyldLog(1, 1, "UdpRecv:CmdIosrItemForceCancel,line=%d\n", 1846);
                version_5 = udpPresLayerHead->Version;
                pkgCount_5 = udpPresLayerHead->PkgCount;
                pkgID_5 = udpPresLayerHead->PkgID;
                pkgSeq_5 = udpPresLayerHead->PkgSeq;
                v15 = HIDWORD(udpPresLayerHead->CycleID);
                cycleID_5[0] = udpPresLayerHead->CycleID;
                cycleID_5[1] = v15;
                pkgBodyLen_5 = udpPresLayerHead->PkgBodyLen;
                if ( pkgBodyLen_5 <= 0x400 )
                {
                  if ( pkgCount_5 )
                  {
                    memcpy(&iosrvItemForceCancelTable + 1024 * (pkgID_5 - 1), &iosrvRecvBuff[32], pkgBodyLen_5);
                    if ( ++itemForceCancelPkgCount == 1 )
                    {
                      isItemForceCancelTimerActived = 1;
                      itemForceCancelTimeOut = 100;
                    }
                    if ( pkgCount_5 != itemForceCancelPkgCount )
                      goto LABEL_84;
                    itemForceCancelPkgCount = 0;
                    isItemForceCancelTimerActived = 0;
                    itemForceCancelTimeOut = 100;
                    result = 38;
                  }
                  else
                  {
                    KyldLog(1, 3, "UdpRecv:CmdIosrItemForceCancel,ERROR!!!pkgCount<=0,pkgCount=%d\n", 0);
                    result = 2;
                  }
                }
                else
                {
                  KyldLog(
                    1,
                    3,
                    "UdpRecv:CmdIosrItemForceCancel,ERROR!!!pkgBodyLen > SUB_PKG_SIZE_MAX,pkgBodyLen=%d\n",
                    pkgBodyLen_5);
                  result = 2;
                }
                break;
              default:
                KyldLog(1, 3, "UdpRecv:recv invalid cmd type.\n");
LABEL_84:
                if ( diagRequestTimeOut > 0 )
                {
                  if ( dataRequestTimeOut > 0 )
                  {
                    if ( dataResendTimeOut > 0 )
                    {
                      if ( itemReadTimeOut > 0 )
                      {
                        if ( itemWriteTimeOut > 0 )
                        {
                          if ( itemForceTimeOut > 0 )
                          {
                            if ( itemForceCancelTimeOut > 0 )
                              goto LABEL_98;
                            KyldLog(1, 3, "UdpRecv:item force cancel recv time out.\n");
                            itemForceCancelPkgCount = 0;
                            isItemForceCancelTimerActived = 0;
                            itemForceCancelTimeOut = 100;
                            result = 70;
                          }
                          else
                          {
                            KyldLog(1, 3, "UdpRecv:item force recv time out.\n");
                            itemForcePkgCount = 0;
                            isItemForceTimerActived = 0;
                            itemForceTimeOut = 100;
                            result = 69;
                          }
                        }
                        else
                        {
                          KyldLog(1, 3, "UdpRecv:item write recv time out.\n");
                          itemWritePkgCount = 0;
                          isItemWriteTimerActived = 0;
                          itemWriteTimeOut = 100;
                          result = 68;
                        }
                      }
                      else
                      {
                        KyldLog(1, 3, "UdpRecv:item read recv time out.\n");
                        itemReadPkgCount = 0;
                        isItemReadTimerActived = 0;
                        itemReadTimeOut = 100;
                        result = 67;
                      }
                    }
                    else
                    {
                      KyldLog(1, 3, "UdpRecv:data resend recv time out.\n");
                      dataResendPkgCount = 0;
                      isDataResendTimerActived = 0;
                      dataResendTimeOut = 100;
                      result = 66;
                    }
                  }
                  else
                  {
                    KyldLog(1, 3, "UdpRecv:data Request recv time out.\n");
                    dataRequestPkgCount = 0;
                    isDataRequestTimerActived = 0;
                    dataRequestTimeOut = 100;
                    result = 65;
                  }
                }
                else
                {
                  KyldLog(1, 3, "UdpRecv:diag Request recv time out.\n");
                  diagRequestPkgCount = 0;
                  isDiagRequestTimerActived = 0;
                  diagRequestTimeOut = 100;
                  result = 64;
                }
                break;
            }
          }
          else
          {
            KyldLog(1, 3, "UdpRecv:IO_GetIOSvrNetIp,ip(%s) is illegal,ioser can not communicate.\n", recvIP);
            result = 2;
          }
        }
        else
        {
          KyldLog(1, 3, "UdpRecv:IO_GetIOSvrNetIp,iosrIPCount<=0,ioser can not communicate.\n");
          result = 2;
        }
      }
      else
      {
        KyldLog(1, 3, "UdpRecv:recvBuff is null.\n");
        result = 2;
      }
    }
  }
  return result;
}

执行时的触发逻辑:
程序调用recvfrom函数接收数据包,在182行中判断发送方的ip地址,如果为192.168.0.2或者192.168.0.3,那么进入188行,可以看出这两个地址是特殊的ip地址,可能用于内部测试。在189行中取出数据包中的命令字段,判断pkgBodyLen<=0x400,pkgCount不为0,那么拷贝iosrvRecvBuff[32]地址处的长度为pkgBodyLen字节的值到地址iosrvDiagRequestTable + 1024 * (pkgID - 1)的地址中,此时如果pkgID为0xffff那么拷贝的目的地址在iosrvDiagRequestTable加偏移0x3fff800的地址,即 0x0241CE80+0x3fff800=641C680。但是该模块内存中的最大地址为0x400000+0x4030000=0x4430000,该地址超出模块在内存中加载后的有效地址空间,访问此地址空间一定造成越界访问异常。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sYJH09EL-1684205261865)(upload/tmp/653410_U6H2GKFYT8MCZVC.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6uZge05s-1684205261865)(upload/tmp/653410_ZEHEKF5YKEMD2AW.png)]

从代码中得知,所有命令(1-9)的处理都存在上述漏洞。

(三) 攻击实现
上述漏洞的触发需要条件是源ip必须是192.168.0.2。没有api可以实现此功能,因此通过安装第三方开发包来实现,这里选用winpcap。
攻击代码主要有以下步骤:

  1. 获取本机网卡和目标网卡的ip和mac,adapter name等信息。
  2. 根据攻击目标的ip地址,找到本机上跟目标ip同一网段下的所有网卡,同时获取目标机器的mac地址,并调用winpcap打开本机上的所有网卡接口。
  3. 将目标网卡的ip,mac,源ip 192.169.0.2等几个参数作为数据包构造的必要参数,调用发包函数,构造造成目标程序溢出的数据包,调用winpcap函数发送。

攻击成功后,目标进程windowsRTE.exe和MaVIEW.exe的cpu利用率从0都上升到30%-40%,说明进程指令空转,右下角的控制台输出大量的异常提示,停止和启动按钮失效,只有重启程序才能恢复正常:

在这里插入图片描述

这时如果用ida挂载则程序发生崩溃。这种现象的解释是,因为异常处理顺序中最优先的是调试器,所以ida挂载后马上接收到异常,选择传递给程序后程序崩溃,选择忽略后则会在ida中继续收到异常。源程序的异常处理程序无法处理这种异常因而造成某些指令的死循环导致cpu使用率异常。

Poc代码在附件中。由于无法上传附件,附件和攻击脚本可点击:点击下载攻击脚本

该软件开发商好像叫做kyland,算是国内该行业的知名厂商。

注意:为了成功编译源码,需要:

  1. 安装winpcap开发包
  2. 本工程若不能编译,右击工程,点击属性-> c/c++ ->预处理器 中添加如下几条宏定义:
    WIN32_LEAN_AND_MEAN
    _WINSOCK_DEPRECATED_NO_WARNINGS
    _XKEYCHECK_H

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/531377.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

freemark模板导出word-01-简单文本内容

在一些项目中&#xff0c;会遇到导出固定格式的word文档&#xff0c;这个时候我们可以使用模板freemarker来实现&#xff0c;本文先分享简单的字符串填充。 比如现在有一个word模板的样式如下 我们填充好内容后(重点坑点&#xff1a;先采用记事本类似的将${A1}编辑好&#xff…

简易画笔效果

使用代码创建纯白图片&#xff0c;图片大小要与image组件大小相同 使用OnDrag触摸的时候将触摸点周围的像素都改为透明 使用shader判断两张图&#xff0c;只要有一张图像素点透明的地方就都透明 shader代码 Shader "Hidden/Draw" {Properties{_MainTex ("Textu…

少儿编程 中国电子学会图形化编程等级考试Scratch编程二级真题解析(判断题)2023年3月

2023年3月scratch编程等级考试二级真题 判断题(共10题,每题2分,共20分) 26、执行完这段程序后,可以在舞台上画出一个正方形 答案:错 考点分析:考查积木综合使用,重点考查画笔积木的使用,从程序中可以看出落笔是在最后,所以在落笔之前绘制的图形是不会显示出来,没…

机器学习服务语音合成,解锁智能养娃新趋势

从翻阅图书绘本到捧着电子书&#xff0c;再到点开手机里的音频APP&#xff0c;随着“互联网阅读”的逐步深入&#xff0c;儿童有声读物越来越受95后父母的欢迎&#xff0c;它的出现令年轻父母摆脱了为孩子讲故事的辛苦&#xff0c;而且有声读物配音发音更加标准&#xff0c;有助…

每日学术速递5.15

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CL 1.Not All Languages Are Created Equal in LLMs: Improving Multilingual Capability by Cross-Lingual-Thought Prompting 标题&#xff1a;并非所有语言在 LLM 中都是平等的&#…

直流电机 PID 控制系统仿真研究(Simulink实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

openGauss数据库3.0.0升级5.0.0操作实践

文章目录 1.1 前言1.2 升级须知升级流程升级方式升级约束 1.3 升级前准备1.4 升级操作1.5 升级验证1.6 提交升级 1.1 前言 openGauss是一款开源关系型数据库管理系统&#xff0c;采用木兰宽松许可证v2发行。之前基于3.0.0版本进行了一些实践&#xff0c;本篇就详细介绍如何将o…

Win7/Win10/Win11系统怎么显示文件后缀

在不同版本的Windows系统中&#xff0c;如Win7/Win10/Win11&#xff0c;显示文件的后缀名可能会有所不同。为了方便用户在进行文件管理时更加方便和高效&#xff0c;本文整理了Win7/Win10/Win11系统中显示文件后缀的具体方法&#xff0c;希望能帮助大家更加轻松地管理自己的文件…

展会进行时!5月16-18日箱讯与您相约中国航交会

宁波国际会展中心7、8号馆 第五届中国&#xff08;宁波&#xff09;国际航运物流交易会 暨2023全球物流企业合作博览会 火爆进行中 箱讯与您相约 8号馆 C033K-C036展位 期待您的光临&#xff01; 2023年5月16-18日&#xff0c;第五届中国&#xff08;宁波&#xff09;国际…

Grafana系列-统一展示-11-Logs Traces无缝跳转

系列文章 Grafana 系列文章 概述 如前文 Grafana 系列 - 统一展示 -1- 开篇所述, Grafana 可以了解所有相关的数据--以及它们之间的关系--对于尽快根治事件和确定意外系统行为的真正来源非常重要。Grafana 允许团队在一个地方对所有的数据进行无缝的可视化和跳转。 最典型的…

MySQL8.0 优化器介绍(四)

GreatSQL社区原创内容未经授权不得随意使用&#xff0c;转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本&#xff0c;使用上与MySQL一致。作者&#xff1a; 奥特曼爱小怪兽文章来源&#xff1a;GreatSQL社区原创 往期回顾 MySQL8.0 优化器介绍&#xff08;一&#x…

Midjourney|文心一格prompt教程[基础篇]:注册使用教程、风格设置、参数介绍、隐私模式等

Midjourney|文心一格prompt教程[基础篇]&#xff1a;注册使用教程、风格设置、参数介绍、隐私模式等 开头讲一下为什么选择Midjourney和文心一格&#xff0c;首先Midjourney功能效果好不多阐述&#xff1b;其次文心一格再多次迭代优化后效果也不错&#xff0c;重点也免费&…

【Kubernetes】| K8s基础组件分析

目录 一. &#x1f981; 前言二. &#x1f981; K8s vs Docker三. &#x1f981; K8s基础组件3.1 Master组件3.1.1 api server3.1.2 controller manager3.1.3 scheduler3.1.4 etcd 3.2 Node组件3.2.1 kublet3.2.2 kube-proxy 四. &#x1f981; 最后 一. &#x1f981; 前言 Ku…

antd-vue-admin——通过链接跳过登录页直接进入系统内部——基础积累

最近在写后台管理系统&#xff0c;遇到一个需求&#xff0c;就是从系统A带参数可以直接进入到系统B内部。不通过系统B的登录页面进行登录。 一般系统的登录&#xff0c;都需要用户名和密码等参数&#xff0c;然后获取到token信息&#xff0c;最后进入到系统内部。 下面介绍具…

5-16SQL每日一题

如下两张表&#xff0c;G0516A和G0516B 要求G0516B按顺序与G0516A的第一个WEEK1依次有序的组合&#xff0c;直到依次组合完毕&#xff0c;预计结果如下&#xff1a; 测试数据&#xff1a; CREATE TABLE G0516A ( WEEKS VARCHAR(10) ) INSERT INTO G0516A VALUES (‘WEEK1…

Socket请求和Http请求区别和场景

我们在开发过程中遇到http请求和socket请求。大部分前后交互都是通过http请求的方式&#xff0c;那socket请求怎么使用&#xff0c;什么情况下使用呢&#xff1f; 基本概念 http请求&#xff1a;基于http协议的soap协议&#xff0c;常见的http数据请求方式有get和post&#xf…

OpenCV实现图像的缩放几何变换,图像金字塔,高斯不同

1.前言 实现图像的放大&#xff08;zoom in&#xff09;和缩小&#xff08;zoom out&#xff09;主要通过两种途径&#xff1a; 几何变换。图像金字塔。 2.几何变换 通过几何变换实现图像放大和缩小功能主要是通过OpenCV的resize函数&#xff1a; 1 2 3 4 5 6 7 8void resi…

二.深度学习yolov5 比特家异构计算 训练与转模型01

(备份笔记 仅记录) 走国产化路上 要离开老黄的NVIDIA了&#xff0c;现在摸索下比特家的异构计算 yolo还停在v3的阶段 因为之前v3就已经够产品化去用了。这次也走下yolov5吧&#xff01; 1.yolov5环境搭建 2.yolov5模型训练 3.yolov5模型测试 4.模型做truck 5.模型转换为…

【六袆 - Design Pattern】Strategy Pattern;策略模式;

JDK8源码使用的策略模式列举 java.util.comparator接口用于对对象进行排序。Comparator接口的compare()方法将两个对象作为参数&#xff0c;并返回一个整数值&#xff0c;表示这两个对象的相对顺序。比较器接口有许多不同的实现&#xff0c;每个实现都有不同的排序算法。例如&a…

OpenPCDet系列 | 5.4 PointPillars算法——AnchorHeadSingle模型预测头模块

文章目录 AnchorHeadTemplate模块1. AnchorGenerator2. ResidualCoder3. AxisAlignedTargetAssigner AnchorHeadSingle模块1. AnchorHeadSingle初始化2. AnchorHeadSingle训练前向传播3. AnchorHeadSingle测试前向传播 OpenPCDet的整个结构图&#xff1a; PointPillars算法属…