日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

Windows TCP/IP遠程執行代碼漏洞分析

 

報告編號:B6-2020-101901

報告來源:360-CERT

報告作者:360-CERT

更新日期:2020-10-19

0x01 前言

1.1 環境搭建

(1)攻擊機環境:Ubuntu 20.04

安裝scapy

sudo apt install Python-pip3
sudo pip3 install scapy

(2)受害機環境:windows 10 1909 x64

tcpip.sys 驅動版本:10.0.18362.476

(3)雙機調試Windows 驅動:

https://blog.csdn.net/qq_21000273/article/details/52027708

斷點:

bp tcpip!Ipv6pUpdateRDNSS
bp tcpip!Ipv6pHandleRouterAdvertisement
bp tcpip!Ipv6pHandleRouterAdvertisement+0xae4cc
bp tcpip!Ipv6pHandleRouterAdvertisement+0xae4db
bp tcpip!Ipv6pUpdateRDNSS+0x99
bp tcpip!Ipv6pUpdateRDNSS+0xca

1.2 背景知識

涉及的包類型:

type:24   Route Information Option
type:25   Recursive DNS Server Option
type:134  IMCPv6 Router Advertisement

涉及的結構:

_MDL結構

typedef __struct_bcount (Size ) struct _MDL {
    struct _MDL *Next ;
    CSHORT Size ;
    CSHORT MdlFlags ;
    struct _EPROCESS *Process ;
    PVOID MAppedSystemVa ;
    PVOID StartVa ;
    ULONG ByteCount ;
    ULONG ByteOffset ;
} MDL , *PMDL ;

_NET_BUFFER 結構

typedef struct _NET_BUFFER {
  union {
    struct {
      PNET_BUFFER Next;
      PMDL        CurrentMdl;
      ULONG       CurrentMdlOffset;
      union {
        ULONG  DataLength;
        SIZE_T stDataLength;
      };
      PMDL        MdlChain;
      ULONG       DataOffset;
    };
    SLIST_HEADER      Link;
    NET_BUFFER_HEADER NetBufferHeader;
  };
  USHORT                ChecksumBias;
  USHORT                Reserved;
  NDIS_HANDLE           NdisPoolHandle;
  PVOID                 NdisReserved[2];
  PVOID                 ProtocolReserved[6];
  PVOID                 MiniportReserved[4];
  NDIS_PHYSICAL_ADDRESS DataPhysicalAddress;
  union {
    PNET_BUFFER_SHARED_MEMORY SharedMemoryInfo;
    PSCATTER_GATHER_LIST      ScatterGatherList;
  };
} NET_BUFFER, *PNET_BUFFER;

相關函數:

NdisGetDataBuffer 函數

PVOID NdisGetDataBuffer(
  PNET_BUFFER NetBuffer,
  ULONG       BytesNeeded,
  PVOID       Storage,
  UINT        AlignMultiple,
  UINT        AlignOffset
);

NetBuffer:指向NET_BUFFER 結構的指針

BytesNeeded:請求的連續數據的字節數

Storage:指向緩沖區的指針,如果調用者未提供緩沖區,則為NULL。緩沖區的大小必須大于或等于BytesNeeded中指定的字節數。如果此值為非NULL,并且請求的數據不連續,則NDIS將請求的數據將復制到Storage指向的地址。

Windows通過Ipv6pHandleRouterAdvertisement 函數處理 IPv6 路由器通告數據,在該函數中調用 NdisGetDataBuffer 函數從 NET_BUFFER 結構中訪問連續或不連續的數據,通過 NET_BUFFER ->CurrentMdlOffset 字段來記錄要訪問數據起始地址相對于_MDL->MappedSystemVa 的偏移。

0x02 漏洞分析

2.1 漏洞背景

2020年10月14日,360CERT監測發現 Microsoft 發布了 TCP/IP遠程代碼執行漏洞 的風險通告,該漏洞是由于Windows TCP/IP堆棧 在處理IMCPv6 Router Advertisement(路由通告)數據包時存在漏洞,遠程攻擊者通過構造特制的ICMPv6 Router Advertisement(路由通告)數據包 ,并將其發送到遠程Windows主機上,可造成遠程BSOD,漏洞編號為CVE-2020-16898。

2.2 漏洞成因

根據rfc5006 描述,RDNSS包的length應為奇數,而當攻擊者構造的RDNSS包的Length為偶數時,Windows TCP/IP 在檢查包過程中會根據Length來獲取每個包的偏移,遍歷解析,導致對 Addresses of IPv6 Recursive DNS Servers 和下一個 RDNSS 選項的邊界解析錯誤,從而繞過驗證,將攻擊者偽造的option包進行解析,造成棧溢出,從而導致系統崩潰。

RDNSS Option 數據包格式如下:

Windows TCP/IP遠程執行代碼漏洞分析

 

Type: 占8-bit,RDNSS 的類型為25

Length:8-bit無符號整數,單位長度為8個字節,所以Type, Length, Reserved, Lifetime一共占8個字節,一個單位長度,而一個IPv6地址占16個字節,兩個單位長度,所以Length的最小值為3,且為奇數。

Reserved:保留字段

Lifetime:32-bit無符號整數,存活周期。

Addresses of IPv6 Recursive DNS Servers:保存RNDSS的IPv6地址,每個占16個字節,地址的數量會影響Length字段,number=(Length - 1) / 2。每增加一個地址,Length加2。

漏洞點存在于tcpip.sys -> Ipv6pHandleRouterAdvertisement 函數

漏洞調用鏈為:Icmpv6ReceiveDatagrams -> Ipv6pHandleRouterAdvertisement -> Ipv6pUpdateRDNSS

Ipv6pHandleRouterAdvertisement 函數存在兩個循環,第一個循環遍歷所有headers,做一些基本的驗證,如length的大小,第二個循環用于處理包,并且該階段不再驗證,兩個循環的偽代碼如下:

// 循環1

while ( 1 )
  {
        ……
    v28 = (KIRQL *)NdisGetDataBuffer(v9, 2u, v182, 1u, 0);
    v27 = v9->DataLength;
    actual_length_bytes = 8 * v28[1];
        ……
    switch ( v25 )
    {
      case 0x18u:       // case 0x18 (ICMPv6NDOptRouteInfo)
            ……
        if ( actual_length_bytes > 0x18u
          || (v144 = *((_BYTE *)NdisGetDataBuffer(v9, actual_length_bytes, v220, 1u, 0) + 2), v144 > 0x80u)
          || v144 > 0x40u && actual_length_bytes < 0x18u  // <-----【1】驗證實際字節數,不能大于0x18
          || v144 && actual_length_bytes < 0x10u )
        {
          *a3 = 24;
          goto LABEL_275;
        }
        break;
      case 0x19u:  // case 0x19 (ICMPv6NDOptRDNSS)    // <-----【2】
        if ( (*(_BYTE *)(v11 + 404) & 0x40) != 0 && actual_length_bytes < 0x18u )  
          *a3 = 25;
        break;
     }
        ……
      if ( actual_length_bytes )
        {
      v31 = actual_length_bytes + v9->CurrentMdlOffset;
      if ( v31 >= *(_Dword *)(v9->Link.Region + 0x28) )
      {
        NdisAdvanceNetBufferDataStart(v9, actual_length_bytes, 0, 0i64);// <---actual_length_bytes=4*8=0x20
      }
      else
      {                                         
        v9->DataOffset += actual_length_bytes;
        v9->DataLength -= actual_length_bytes;
        v9->CurrentMdlOffset = v31;        // 更新CurrentMdlOffset
      }
    }
    v21 += actual_length_bytes;
  }

    ……

// 循環2 
while ( 1 )
{
    ……
     if ( *v75 == 0x18 )                   // case 0x18 (ICMPv6NDOptRouteInfo)
          {
                   ……
            v153 = (unsigned __int8 *)NdisGetDataBuffer(NetBuffer_1, actual_option, Storage_1, 1u, 0); // <--- 【3】
            v225 = _mm_load_si128((const __m128i *)&_xmm);
            v174 = v225.m128i_u32[((unsigned __int64)v153[3] >> 3) & 3];
                 ……
          }
          if ( *v75 == 0x19 )      // case 0x19 (ICMPv6NDOptRDNSS)
          {
            if ( (*(_BYTE *)(v11 + 0x194) & 0x40) != 0 )
            {
              Ipv6pUpdateRDNSS(v11, NetBuffer_1, Buf2, v189, &v170);  // <---- 【4】
              goto LABEL_309;
            }
          }
          else if ( *v75 == 31 && (*(_BYTE *)(v11 + 404) & 0x40) != 0 )
          {
            Ipv6pUpdateDNSSL(v11, NetBuffer_1, Buf2, (unsigned int)v189, &v170);
LABEL_309:
            v77 = v166;
            goto LABEL_118;
          }
                ……
}

第一個循環用于驗證各個header的有效性,首先獲取第一個option包,length為0x4,實際字節數為length*8=0x20個字節,首先更新_net_buffer結構,根據實際字節數計算option的偏移,解析到后面的option2,后面依次根據option.length 解析到option3, option4 ……

Windows TCP/IP遠程執行代碼漏洞分析

 

所以并沒有處理'x18x22',因此繞過了【1】處case:0x18中對length的驗證。所以如果Option1.length設為3時,構造圖中的包由于長度0x22校驗不通過,會當成無效包被舍棄。

第二個循環處理各個option包,但在case:0x19 的Ipv6pUpdateRDNSS函數中,計算ipv6地址個數是通過(length-1)/2 ,這樣導致length=0x4時和length=0x3時計算的結果一樣,都是根據ipv6地址個數*8+8(Type/Length/ Reserved/Lifetime),所以跳過0x18個字節解析到'x18x22',將其當成了type=0x18的option包,并且沒有了長度的驗證。

Windows TCP/IP遠程執行代碼漏洞分析

 

綜上,漏洞是由于檢查和解析包時根據length計算的偏移不同,導致繞過檢查,解析到攻擊者偽造的option包,造成棧溢出。

0x03 漏洞利用

具體調試利用過程如下:

(1)首先進入循環1中的【2】處,判斷length實際字節數是否小于0x18,然后調用NdisAdvanceNetBufferDataStart,更新_NET_BUFFER結構,得到下一個Option的偏移,依次處理后面的Option:

Windows TCP/IP遠程執行代碼漏洞分析

 

調用NdisAdvanceNetBufferDataStart前:

kd> dt ndis!_NET_BUFFER @r14
   +0x000 Next             : (null) 
   +0x008 CurrentMdl       : 0xffffe20b`aea77e70 _MDL
   +0x010 CurrentMdlOffset : 0x10
   +0x018 DataLength       : 0x188
   +0x018 stDataLength     : 0x188
   +0x020 MdlChain         : 0xffffe20b`b0a9c220 _MDL
   +0x028 DataOffset       : 0x70
   +0x000 Link             : _SLIST_HEADER
   +0x000 NetBufferHeader  : _NET_BUFFER_HEADER
   +0x030 ChecksumBias     : 0
   +0x032 Reserved         : 0
   +0x038 NdisPoolHandle   : 0xffffe20b`ae45cb40 Void
   +0x040 NdisReserved     : [2] (null) 
   +0x050 ProtocolReserved : [6] 0x00000198`00000000 Void
   +0x080 MiniportReserved : [4] (null) 
   +0x0a0 DataPhysicalAddress : _LARGE_INTEGER 0x0
   +0x0a8 SharedMemoryInfo : (null) 
   +0x0a8 ScatterGatherList : (null) 

kd> dt ndis!_MDL 0xffffe20b`aea77e70
   +0x000 Next             : 0xffffe20b`aea77b10 _MDL
   +0x008 Size             : 0n56
   +0x00a MdlFlags         : 0n4
   +0x00c AllocationProcessorNumber : 0xffff
   +0x00e Reserved         : 0xffff
   +0x010 Process          : (null) 
   +0x018 MappedSystemVa   : 0xffffe20b`aea77eb0 Void
   +0x020 StartVa          : 0xffffe20b`aea77000 Void
   +0x028 ByteCount        : 0x30
   +0x02c ByteOffset       : 0xeb0
kd> db 0xffffe20b`aea77eb0+0x10
ffffe20b`aea77ec0  19 04 00 00 00 00 03 84-30 30 30 30 30 30 30 30  ........00000000    // <--- Option1
ffffe20b`aea77ed0  30 30 30 30 30 30 30 30-18 22 fd 81 00 00 03 84  00000000."......
ffffe20b`aea77ee0  00 bf 09 02 73 6d 41 72-00 00 03 00 dd bf 04 04  ....smAr........   

調用NdisAdvanceNetBufferDataStart后:

kd> dt ndis!_NET_BUFFER @r14
   +0x000 Next             : (null) 
   +0x008 CurrentMdl       : 0xffffe20b`aea77b10 _MDL
   +0x010 CurrentMdlOffset : 0
   +0x018 DataLength       : 0x168
   +0x018 stDataLength     : 0x168
   +0x020 MdlChain         : 0xffffe20b`b0a9c220 _MDL
   +0x028 DataOffset       : 0x90
   +0x000 Link             : _SLIST_HEADER
   +0x000 NetBufferHeader  : _NET_BUFFER_HEADER
   +0x030 ChecksumBias     : 0
   +0x032 Reserved         : 0
   +0x038 NdisPoolHandle   : 0xffffe20b`ae45cb40 Void
   +0x040 NdisReserved     : [2] (null) 
   +0x050 ProtocolReserved : [6] 0x00000198`00000000 Void
   +0x080 MiniportReserved : [4] (null) 
   +0x0a0 DataPhysicalAddress : _LARGE_INTEGER 0x0
   +0x0a8 SharedMemoryInfo : (null) 
   +0x0a8 ScatterGatherList : (null) 

kd>   dt ndis!_MDL 0xffffe20b`aea77b10
   +0x000 Next             : 0xffffe20b`aea78890 _MDL
   +0x008 Size             : 0n56
   +0x00a MdlFlags         : 0n4
   +0x00c AllocationProcessorNumber : 0xe20b
   +0x00e Reserved         : 0xffff
   +0x010 Process          : (null) 
   +0x018 MappedSystemVa   : 0xffffe20b`aea77b50 Void
   +0x020 StartVa          : 0xffffe20b`aea77000 Void
   +0x028 ByteCount        : 0x30
   +0x02c ByteOffset       : 0xb50
kd> db 0xffffe20b`aea77b50
ffffe20b`aea77b50  19 05 00 00 00 00 03 84-41 41 41 41 41 41 41 41  ........AAAAAAAA    // <--- Option2
ffffe20b`aea77b60  41 41 41 41 41 41 41 41-42 42 42 42 42 42 42 42  AAAAAAAABBBBBBBB
ffffe20b`aea77b70  42 42 42 42 42 42 42 42-19 05 00 00 00 00 03 84  BBBBBBBB........

(2)進入循環2中的【4】處:

Windows TCP/IP遠程執行代碼漏洞分析

 

進入Ipv6UpdateRDNSS,處理第一個type為0x19,length為4的option,Ipv6pUpdateRDNSS 中計算IPv6 地址數量是通過下面代碼實現的:

Windows TCP/IP遠程執行代碼漏洞分析

 

調試結果如下:

Windows TCP/IP遠程執行代碼漏洞分析

 

rbx 保存option 包的起始位置,[rbx+1] 取的是length字段的值,此時為4,esi的值為1,ecx的值為2,所以這段匯編的計算的ipv6地址個數為(length-1)/2 =1 .

所以length設置為4,其實和length=3計算結果是相同的:

(4-1)/2 = 1
(3-1)/2 = 1

因此會按照0x18(一個ipv6地址加上Type/Length/ Reserved/Lifetime) 的偏移進行解析下一個Option,即解析到偽造的Option。

調用Ipv6UpdateRDNSS前:

kd> dt ndis!_NET_BUFFER @r14
   +0x000 Next             : (null) 
   +0x008 CurrentMdl       : 0xffffe20b`aea77e70 _MDL
   +0x010 CurrentMdlOffset : 0x10
   +0x018 DataLength       : 0x188
   +0x018 stDataLength     : 0x188
   +0x020 MdlChain         : 0xffffe20b`b0a9c220 _MDL
   +0x028 DataOffset       : 0x70
   +0x000 Link             : _SLIST_HEADER
   +0x000 NetBufferHeader  : _NET_BUFFER_HEADER
   +0x030 ChecksumBias     : 0
   +0x032 Reserved         : 0
   +0x038 NdisPoolHandle   : 0xffffe20b`ae45cb40 Void
   +0x040 NdisReserved     : [2] (null) 
   +0x050 ProtocolReserved : [6] 0x00000198`00000000 Void
   +0x080 MiniportReserved : [4] (null) 
   +0x0a0 DataPhysicalAddress : _LARGE_INTEGER 0x0
   +0x0a8 SharedMemoryInfo : (null) 
   +0x0a8 ScatterGatherList : (null) 
kd> dt ndis!_MDL 0xffffe20b`aea77e70
   +0x000 Next             : 0xffffe20b`aea77b10 _MDL
   +0x008 Size             : 0n56
   +0x00a MdlFlags         : 0n4
   +0x00c AllocationProcessorNumber : 0xffff
   +0x00e Reserved         : 0xffff
   +0x010 Process          : (null) 
   +0x018 MappedSystemVa   : 0xffffe20b`aea77eb0 Void
   +0x020 StartVa          : 0xffffe20b`aea77000 Void
   +0x028 ByteCount        : 0x30
   +0x02c ByteOffset       : 0xeb0
kd> db 0xffffe20b`aea77eb0+0x10
ffffe20b`aea77ec0  19 04 00 00 00 00 03 84-30 30 30 30 30 30 30 30  ........00000000  // <--- Option1
ffffe20b`aea77ed0  30 30 30 30 30 30 30 30-18 22 fd 81 00 00 03 84  00000000."......
ffffe20b`aea77ee0  00 bf 09 02 73 6d 41 72-00 00 03 00 dd bf 04 04  ....smAr........

調用Ipv6UpdateRDNSS后:

kd> dt ndis!_NET_BUFFER @r14
   +0x000 Next             : (null) 
   +0x008 CurrentMdl       : 0xffffe20b`aea77e70 _MDL
   +0x010 CurrentMdlOffset : 0x28
   +0x018 DataLength       : 0x170
   +0x018 stDataLength     : 0x170
   +0x020 MdlChain         : 0xffffe20b`b0a9c220 _MDL
   +0x028 DataOffset       : 0x88
   +0x000 Link             : _SLIST_HEADER
   +0x000 NetBufferHeader  : _NET_BUFFER_HEADER
   +0x030 ChecksumBias     : 0
   +0x032 Reserved         : 0
   +0x038 NdisPoolHandle   : 0xffffe20b`ae45cb40 Void
   +0x040 NdisReserved     : [2] (null) 
   +0x050 ProtocolReserved : [6] 0x00000198`00000000 Void
   +0x080 MiniportReserved : [4] (null) 
   +0x0a0 DataPhysicalAddress : _LARGE_INTEGER 0x0
   +0x0a8 SharedMemoryInfo : (null) 
   +0x0a8 ScatterGatherList : (null) 
kd> dt ndis!_MDL 0xffffe20b`aea77e70
   +0x000 Next             : 0xffffe20b`aea77b10 _MDL
   +0x008 Size             : 0n56
   +0x00a MdlFlags         : 0n4
   +0x00c AllocationProcessorNumber : 0xffff
   +0x00e Reserved         : 0xffff
   +0x010 Process          : (null) 
   +0x018 MappedSystemVa   : 0xffffe20b`aea77eb0 Void
   +0x020 StartVa          : 0xffffe20b`aea77000 Void
   +0x028 ByteCount        : 0x30
   +0x02c ByteOffset       : 0xeb0
kd> db 0xffffe20b`aea77eb0+0x28
ffffe20b`aea77ed8  18 22 fd 81 00 00 03 84-00 bf 09 02 73 6d 41 72  ."..........smAr // <---  偽造的option
ffffe20b`aea77ee8  00 00 03 00 dd bf 04 04-00 60 6d b0 0b e2 ff ff  .........`m.....

(3)進入循環2中的【3】處case:0x18,處理偽造的type為0x18,length為0x22的option。

對于type為0x18會進入下面的流程處理,調用NdisGetDataBuffer函數,其中第二個參數為長度的實際字節大小,等于length8,所以此時傳入的actual_length_bytes = 0x22 8 = 0x110:

Windows TCP/IP遠程執行代碼漏洞分析

 

而Storage_1 為棧上的數組變量,將0x110個字節賦值過去,就會造成棧上的溢出,實際的崩潰是溢出覆蓋了stack cookie,觸發tcpip!_security_check_cookie,造成藍屏(BSOD):

Windows TCP/IP遠程執行代碼漏洞分析

 

調用NdisGetDataBuffer函數前:

kd> r rdx  // actual_length_bytes_1
rdx=0000000000000110
kd> dd r8 // Storage_1
fffff806`6ce9a348  00000000 00000000 00000000 00000000
fffff806`6ce9a358  00000000 00000000 00000000 00000000
fffff806`6ce9a368  00000000 00000000 b3b18770 ffffe20b
fffff806`6ce9a378  aea77eb0 ffffe20b b021bce0 ffffe20b
fffff806`6ce9a388  00000000 00000000 aea77eb0 ffffe20b
fffff806`6ce9a398  00000000 00000000 b0210040 00000000

調用NdisGetDataBuffer函數后:

kd> dd fffff806`6ce9a348
fffff806`6ce9a348  81fd2218 84030000 00000519 84030000
fffff806`6ce9a358  41414141 41414141 41414141 41414141
fffff806`6ce9a368  42424242 42424242 42424242 42424242
fffff806`6ce9a378  00000519 84030000 41414141 41414141
fffff806`6ce9a388  41414141 41414141 42424242 42424242
kd> k
Child-SP          RetAddr           Call Site
fffff806`6ce9a090 42424242`42424242 tcpip!Ipv6pHandleRouterAdvertisement+0xae522
fffff806`6ce9a440 84030000`00000519 0x42424242`42424242
fffff806`6ce9a448 41414141`41414141 0x84030000`00000519
fffff806`6ce9a450 41414141`41414141 0x41414141`41414141
fffff806`6ce9a458 00000000`00000000 0x41414141`41414141

最后需要注意的是如果從NetBuffer_1請求的數據是連續的,則會將數據存放在NDIS提供的地址,這樣無法造成溢出。所以需要從NetBuffer_1請求的數據不是連續的,才會將數據存放在Storage_1上。數據非連續的實現是通過 fragmentation(碎片化),將Router Advertisement包通過scapy的fragment6函數拆分成多個IPv6 fragments進行發送。

藍屏崩潰現場:

Windows TCP/IP遠程執行代碼漏洞分析

 

0x04 補丁分析

補丁前第一個循環case:0x19的偽代碼:

Windows TCP/IP遠程執行代碼漏洞分析

 

補丁后:

Windows TCP/IP遠程執行代碼漏洞分析

 

補丁加入了針對length的奇偶驗證,v32為length *8的結果, 如果 length 為偶數,(v32-8)&0xf 將不等于0,則轉入錯誤處理流程。

0x05 時間線

2020-10-13 微軟發布漏洞通告

2020-10-14 360CERT發布通告

2020-10-16 360CERT監測到網上公開相關Poc

2020-10-16 360CERT更新通告

2020-10-19 360CERT發布漏洞分析報告

0x06 參考鏈接

  1. https://tools.ietf.org/html/rfc8106
  2. https://www.mcafee.com/blogs/other-blogs/mcafee-labs/cve-2020-16898-bad-neighbor
  3. http://blog.pi3.com.pl/?p=780
  4. https://blog.quarkslab.com/beware-the-bad-neighbor-analysis-and-poc-of-the-windows-ipv6-router-advertisement-vulnerability-cve-2020-16898.html

分享到:
標簽:漏洞 分析
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定