80,443 - Pentesting Web Methodology
Tip
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
基本信息
Web 服务是最常见且最广泛的服务,并且存在许多不同类型的漏洞。
默认端口: 80 (HTTP), 443(HTTPS)
PORT STATE SERVICE
80/tcp open http
443/tcp open ssl/https
nc -v domain.com 80 # GET / HTTP/1.0
openssl s_client -connect domain.com:443 # GET / HTTP/1.0
Web API 指南
方法论摘要
在这个方法论中,我们假定你要攻击一个 domain(或 subdomain),仅此而已。因此,你应该将此方法论应用到每个在 scope 内发现的 domain、subdomain 或未确定 web server 的 IP 上。
- 从 识别 web server 使用的 技术(technologies) 开始。如果你能成功识别出技术,寻找在后续测试中需要记住的 tricks。
- 该技术版本是否存在任何 known vulnerability?
- 使用任何 well known tech?有没有任何 useful trick 可以提取更多信息?
- 是否需要运行任何 specialised scanner(例如 wpscan)?
- 启动 general purposes scanners。你永远不知道它们是否会发现什么或提供一些有趣的信息。
- 从 initial checks 开始:robots、sitemap、404 error 和 SSL/TLS scan(如果是 HTTPS)。
- 开始 spidering 页面:现在是时候 find 所有可能的 files, folders 和正在使用的 parameters。同时,检查是否有 special findings。
- 注意:每当在 brute-forcing 或 spidering 过程中发现新的目录时,应对其进行 spidering。
- Directory Brute-Forcing:尝试对所有发现的文件夹进行 bruteforce,以搜索新的 files 和 directories。
- 注意:每当在 brute-forcing 或 spidering 过程中发现新的目录时,应对其进行 Brute-Forced。
- Backups checking:通过追加常见的备份扩展名,测试是否可以找到已发现文件的 backups。
- Brute-Force parameters:尝试 find hidden parameters。
- 一旦你 identified 所有可能接受 user input 的 endpoints,检查与之相关的各种 vulnerabilities。
- Follow this checklist
Server Version (Vulnerable?)
Identify
检查正在运行的 server version 是否存在已知的 known vulnerabilities。
响应的 HTTP headers and cookies 对 identify 所使用的 technologies 和/或 version 非常有用。Nmap scan 可以识别 server 版本,但下列工具也可能有用:whatweb, webtech 或 https://builtwith.com/:
whatweb -a 1 <URL> #Stealthy
whatweb -a 3 <URL> #Aggresive
webtech -u <URL>
webanalyze -host https://google.com -crawl 2
搜索 vulnerabilities of the web application version
检查是否存在 WAF
- https://github.com/EnableSecurity/wafw00f
- https://github.com/Ekultek/WhatWaf.git
- https://nmap.org/nsedoc/scripts/http-waf-detect.html
Web 技术技巧
一些用于在不同已知技术中发现漏洞的技巧,针对正在使用的不同技术:
- AEM - Adobe Experience Cloud
- Apache
- Artifactory
- Buckets
- CGI
- Custom UDP RPC Protocols
- Dotnet SOAP WSDL client exploitation
- Drupal
- Flask
- Fortinet FortiWeb
- Git
- Golang
- GraphQL
- H2 - Java SQL database
- ISPConfig
- IIS tricks
- Microsoft SharePoint
- JBOSS
- Jenkins
- Jira
- Joomla
- JSP
- Laravel
- Moodle
- Nginx
- PHP (php has a lot of interesting tricks that could be exploited)
- Python
- Roundcube
- Spring Actuators
- Symphony
- Tomcat
- VMWare
- Web API Pentesting
- WebDav
- Werkzeug
- Wordpress
- Electron Desktop (XSS to RCE)
- Sitecore
- Zabbix
请注意,相同的域名在不同的端口、文件夹或子域下可能使用不同的技术。\
如果 Web 应用使用了任何上面列出的知名tech/platform或其他平台,别忘了在互联网上搜索新的技巧(并告知我!)。
源代码审查
如果应用的source code可以在 github 上获取,除了你自己对应用进行 White box test 外,可能还有一些信息对当前的 Black-Box testing 有用:
- 是否有可通过 web 访问的 Change-log or Readme or Version 文件或任何包含版本信息的内容?
- 凭证(credentials)如何以及在哪里保存?是否有任何(可访问的?)包含凭证(用户名或 passwords)的 file?
- 密码(passwords)是以 plain text 存储、encrypted,还是使用了哪种 hashing algorithm?
- 是否使用任何用于加密的 master key?使用了哪种 algorithm?
- 能否通过利用某些 vulnerability 访问这些文件中的任意一个?
- 在 github 的 issues(已解决或未解决)中是否有任何有趣的信息?或者在 commit history 中(也许某个旧的 commit 引入了某个 password)?
Source code Review / SAST Tools
自动化扫描器
General purpose automatic scanners
nikto -h <URL>
whatweb -a 4 <URL>
wapiti -u <URL>
W3af
zaproxy #You can use an API
nuclei -ut && nuclei -target <URL>
# https://github.com/ignis-sec/puff (client side vulns fuzzer)
node puff.js -w ./wordlist-examples/xss.txt -u "http://www.xssgame.com/f/m4KKGHi2rVUN/?query=FUZZ"
CMS 扫描器
如果使用 CMS,别忘了运行扫描器,可能会发现有价值的信息:
Clusterd: JBoss, ColdFusion, WebLogic, Tomcat, Railo, Axis2, Glassfish
CMSScan: WordPress, Drupal, Joomla, vBulletin 用于检测网站的安全问题。 (GUI)
VulnX: Joomla, Wordpress, Drupal, PrestaShop, Opencart
CMSMap: (W)ordpress, (J)oomla, (D)rupal 或 (M)oodle
droopscan: Drupal, Joomla, Moodle, Silverstripe, Wordpress
cmsmap [-f W] -F -d <URL>
wpscan --force update -e --url <URL>
joomscan --ec -u <URL>
joomlavs.rb #https://github.com/rastating/joomlavs
此时你应该已经掌握了客户端所使用的 web 服务器的一些信息(如果有提供任何数据)以及在测试过程中需要牢记的一些技巧。如果幸运,你甚至可能已经找到一个 CMS 并运行了一些扫描器。
Web 应用逐步发现
从此处开始,我们将开始与 web 应用进行交互。
初步检查
包含有用信息的默认页面:
- /robots.txt
- /sitemap.xml
- /crossdomain.xml
- /clientaccesspolicy.xml
- /.well-known/
- 还要检查主页面和次要页面中的注释。
强制触发错误
当向 web 服务器发送异常数据时,服务器可能会表现异常。这可能导致漏洞或敏感信息泄露。
- 访问 fake pages,例如 /whatever_fake.php (.aspx,.html,.etc)
- 在 cookie 值 和 参数 值 中添加 “[]”, “]]”, 和 “[[” 来制造错误
- 通过在 URL 末尾提供输入为
/~randomthing/%s来触发错误 - 尝试不同的 HTTP Verbs,例如 PATCH、DEBUG,或非法的 FAKE
检查是否可以上传文件 (PUT verb, WebDav)
如果发现 WebDav 被启用,但在根文件夹中没有足够的上传文件权限,尝试:
- Brute Force credentials
- 使用 WebDav 在网页内其他已发现的文件夹 Upload files。你可能在其他文件夹拥有上传权限。
SSL/TLS 漏洞
- 如果应用程序未在任何部分强制使用 HTTPS,则易受 MitM 攻击
- 如果应用程序通过 HTTP 发送敏感数据(例如密码),则这是一个高风险漏洞。
使用 testssl.sh 检查 vulnerabilities(在 Bug Bounty 计划中这类漏洞可能不会被接受),并使用 a2sv 重新检查这些漏洞:
./testssl.sh [--htmlfile] 10.10.10.10:443
#Use the --htmlfile to save the output inside an htmlfile also
# You can also use other tools, by testssl.sh at this momment is the best one (I think)
sslscan <host:port>
sslyze --regular <ip:port>
Information about SSL/TLS vulnerabilities:
- https://www.gracefulsecurity.com/tls-ssl-vulnerabilities/
- https://www.acunetix.com/blog/articles/tls-vulnerabilities-attacks-final-part/
Spidering
在目标网站内部启动某种类型的 spider。spider 的目标是从被测应用中找到尽可能多的路径。因此,应该结合 web crawling 和外部来源来发现尽可能多的有效路径。
- gospider (go): HTML spider,能在 JS 文件中使用 LinkFinder,并查询外部来源 (Archive.org, CommonCrawl.org, VirusTotal.com)。
- hakrawler (go): HML spider,针对 JS 文件有 LinkFinder,并使用 Archive.org 作为外部来源。
- dirhunt (python): HTML spider,同时标示“juicy files”。
- evine (go): 交互式 CLI HTML spider。它也会在 Archive.org 搜索。
- meg (go): 该工具不是 spider,但很有用。你可以提供一个 hosts 文件和一个 paths 文件,meg 会对每个主机获取每个路径并保存响应。
- urlgrab (go): 带有 JS 渲染能力的 HTML spider。但看起来未维护,预编译版本较旧,当前代码无法编译。
- gau (go): 使用外部提供者(wayback、otx、commoncrawl)的 HTML spider。
- ParamSpider: 该脚本将查找带参数的 URL 并列出它们。
- galer (go): 带 JS 渲染能力的 HTML spider。
- LinkFinder (python): HTML spider,具有 JS beautify 能力,可在 JS 文件中搜索新路径。也可以看一下 JSScanner,它是 LinkFinder 的一个包装器。
- goLinkFinder (go): 用于从 HTML 源和嵌入的 javascript 文件中提取 endpoints。对 bug hunters、red teamers、infosec ninjas 很有用。
- JSParser (python2.7): 一个使用 Tornado 和 JSBeautifier 的 python 2.7 脚本,用于从 JavaScript 文件解析相对 URL,便于发现 AJAX 请求。看起来未维护。
- relative-url-extractor (ruby): 给定一个文件 (HTML) 它会使用巧妙的正则表达式从混淆(minify)文件中提取相对 URL。
- JSFScan (bash, several tools): 使用多个工具从 JS 文件中收集有趣信息。
- subjs (go): 查找 JS 文件。
- page-fetch (go): 在 headless browser 中加载页面并打印为加载页面而加载的所有 urls。
- Feroxbuster (rust): 内容发现工具,融合了前述工具的多个选项。
- Javascript Parsing: 一个 Burp 扩展,用于在 JS 文件中查找 path 和 params。
- BurpJSLinkFinder Enhanced: Burp 扩展 (Jython),被动分析 JavaScript 响应(按 MIME 类型 和
/js路径)以提取 endpoints/links,并可选地标记嵌入的 secrets 及其严重性。 - Sourcemapper: 给定 .js.map URL 时,获取 beautified JS 代码 的工具。
- xnLinkFinder: 用于为给定目标发现 endpoints 的工具。
- waymore: 从 wayback machine 发现链接(也会下载 wayback 中的响应并查找更多链接)。
- HTTPLoot (go): 爬取(甚至通过填表单)并使用特定正则查找敏感信息。
- SpiderSuite: Spider Suite 是为网络安全专业人士设计的高级多功能 GUI web security Crawler/Spider。
- jsluice (go): 一个 Go package 和 command-line tool,用于从 JavaScript 源代码中提取 URLs、paths、secrets 和其他有趣数据。
- ParaForge: ParaForge 是一个简单的 Burp Suite extension,用于从请求中提取参数和 endpoints,以创建用于 fuzzing 和枚举的自定义 wordlist。
- katana (go): 处理此类工作的优秀工具。
- Crawley (go): 打印它能找到的每一个 link。
Brute Force directories and files
从根目录开始进行 brute-forcing,并确保对使用此方法发现的所有目录以及通过 Spidering 发现的所有目录都进行 brute-force(你可以递归地进行此类 brute-forcing,并在所用 wordlist 前面添加已发现目录的名称)。
工具:
- Dirb / Dirbuster - 包含在 Kali 中,老(且慢)但可用。允许自签名证书和递归搜索。与其他选项相比太慢。
- Dirsearch (python): 它不允许自签名证书但支持递归搜索。
- Gobuster (go): 支持自签名证书,但不支持递归搜索。
- Feroxbuster - Fast, supports recursive search.
- wfuzz
wfuzz -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt https://domain.com/api/FUZZ - ffuf - Fast:
ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.10/FUZZ - uro (python): 这不是 spider,而是一个工具,给定已发现 URL 列表后会删除“重复”的 URL。
- Scavenger: Burp 扩展,从不同页面的 burp 历史记录创建目录列表。
- TrashCompactor: 根据 js imports 删除具有重复功能的 URL。
- Chamaleon: 使用 wapalyzer 检测所用技术并选择相应的 wordlists。
Recommended dictionaries:
- https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/bf_directories.txt
- Dirsearch included dictionary
- http://gist.github.com/jhaddix/b80ea67d85c13206125806f0828f4d10
- Assetnote wordlists
- https://github.com/danielmiessler/SecLists/tree/master/Discovery/Web-Content
- raft-large-directories-lowercase.txt
- directory-list-2.3-medium.txt
- RobotsDisallowed/top10000.txt
- https://github.com/random-robbie/bruteforce-lists
- https://github.com/google/fuzzing/tree/master/dictionaries
- https://github.com/six2dez/OneListForAll
- https://github.com/random-robbie/bruteforce-lists
- https://github.com/ayoubfathi/leaky-paths
- /usr/share/wordlists/dirb/common.txt
- /usr/share/wordlists/dirb/big.txt
- /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
注意:每当在 brute-forcing 或 spidering 过程中发现新目录时,都应对其进行 Brute-Forcing。
What to check on each file found
- Broken link checker: 在 HTML 中查找可能导致 takeover 的断链。
- File Backups: 找到所有文件后,查找可执行文件的备份(“.php”, “.aspx”…)。常见的备份命名变体包括: file.ext~, #file.ext#, ~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp 和 file.old. 你也可以使用工具 bfac 或 backup-gen。
- Discover new parameters: 你可以使用类似 Arjun, parameth, x8 和 Param Miner 的工具来发现隐藏参数。如果可能,应尝试在每个可执行的 web 文件上搜索隐藏参数。
- Arjun all default wordlists: https://github.com/s0md3v/Arjun/tree/master/arjun/db
- Param-miner “params” : https://github.com/PortSwigger/param-miner/blob/master/resources/params
- Assetnote “parameters_top_1m”: https://wordlists.assetnote.io/
- nullenc0de “params.txt”: https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773
- Comments: 检查所有文件的注释,可能会发现 credentials 或 hidden functionality。
- 如果你在打 CTF,一个“常见”的技巧是在页面源码的右侧注释中使用大量空格来隐藏信息(这样在浏览器打开源码时看不到数据)。另一种方式是使用多行换行并在页面底部的注释中隐藏信息。
- API keys: 如果你发现任何 API key,有一些项目可以帮助你利用不同平台的 API keys: keyhacks, zile, truffleHog, SecretFinder, RegHex, DumpsterDive, EarlyBird
- Google API keys: 如果你发现任何看起来像 AIzaSyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik 的 API key,可以使用项目 gmapapiscanner 来检查该 key 可以访问哪些 apis。
- S3 Buckets: 在 spidering 时查看是否有任何 subdomain 或 link 与某个 S3 bucket 相关。如果是这样,请检查该 bucket 的 permissions。
Special findings
在执行 spidering 和 brute-forcing 时,你可能会发现一些需要注意的有趣事项。
Interesting files
- 在 CSS 文件中查找指向其他文件的 links。
- If you find a .git file some information can be extracted
- 如果你找到 .env,可能会发现 api keys、db 密码和其他信息。
- 如果你找到 API endpoints,你应该也去测试它们。这些不是文件,但通常“看起来像”文件。
- JS files: 在 spidering 部分提到了多种可从 JS 文件中提取路径的工具。此外,建议对每个发现的 JS 文件进行监控,因为在某些情况下,文件的变化可能表明代码中引入了潜在的漏洞。你可以使用例如 JSMon。
- 你还应该用 RetireJS 或 JSHole 检查已发现的 JS 文件,看是否存在已知漏洞。
- Javascript Deobfuscator and Unpacker: https://lelinhtinh.github.io/de4js/, https://www.dcode.fr/javascript-unobfuscator
- Javascript Beautifier: http://jsbeautifier.org/, http://jsnice.org/
- JsFuck deobfuscation (javascript with chars:“[]!+” https://enkhee-osiris.github.io/Decoder-JSFuck/)
- TrainFuck:
+72.+29.+7..+3.-67.-12.+55.+24.+3.-6.-8.-67.-23. - 在许多场合,你需要理解所使用的正则表达式。以下资源会很有用: https://regex101.com/ 或 https://pythonium.net/regex
- 你也可以监控检测到表单的文件,因为参数的变化或新表单的出现可能表明潜在的新易受攻击功能。
403 Forbidden/Basic Authentication/401 Unauthorized (bypass)
502 Proxy Error
如果任何页面以该 code 响应,可能是 proxy 配置错误。如果你发送一个像 GET https://google.com HTTP/1.1 的 HTTP 请求(带上 host header 和其他常见 header),该 proxy 会尝试访问 google.com,此时你就会发现一个 SSRF。
NTLM Authentication - Info disclosure
如果运行的服务器要求身份验证的是 Windows,或者你发现一个登录要求你的 credentials(并要求 domain name),你可以触发 信息泄露。
发送 头部: “Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”,由于 NTLM authentication 的工作方式,服务器会在头部 “WWW-Authenticate” 中返回内部信息(IIS 版本、Windows 版本等)。
你可以使用 nmap 插件 “http-ntlm-info.nse” 来自动化这一过程。
HTTP Redirect (CTF)
可以在重定向中放置内容。这些内容不会显示给用户(因为浏览器会执行重定向),但可能在其中隐藏信息。
Web Vulnerabilities Checking
在对 web 应用进行了全面枚举之后,就该检查大量可能的漏洞了。检查清单在这里:
Web Vulnerabilities Methodology
关于 web 漏洞的更多信息:
- https://six2dez.gitbook.io/pentest-book/others/web-checklist
- https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web_application_security_testing/configuration_and_deployment_management_testing.html
- https://owasp-skf.gitbook.io/asvs-write-ups/kbid-111-client-side-template-injection
Monitor Pages for changes
你可以使用诸如 https://github.com/dgtlmoon/changedetection.io 的工具来监控页面变化,以发现可能引入漏洞的修改。
HackTricks Automatic Commands
HackTricks Automatic Commands
```yaml Protocol_Name: Web #Protocol Abbreviation if there is one. Port_Number: 80,443 #Comma separated if there is more than one. Protocol_Description: Web #Protocol Abbreviation Spelled outEntry_1: Name: Notes Description: Notes for Web Note: | https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/index.html
Entry_2: Name: Quick Web Scan Description: Nikto and GoBuster Command: nikto -host {Web_Proto}://{IP}:{Web_Port} &&&& gobuster dir -w {Small_Dirlist} -u {Web_Proto}://{IP}:{Web_Port} && gobuster dir -w {Big_Dirlist} -u {Web_Proto}://{IP}:{Web_Port}
Entry_3: Name: Nikto Description: Basic Site Info via Nikto Command: nikto -host {Web_Proto}://{IP}:{Web_Port}
Entry_4: Name: WhatWeb Description: General purpose auto scanner Command: whatweb -a 4 {IP}
Entry_5: Name: Directory Brute Force Non-Recursive Description: Non-Recursive Directory Brute Force Command: gobuster dir -w {Big_Dirlist} -u {Web_Proto}://{IP}:{Web_Port}
Entry_6: Name: Directory Brute Force Recursive Description: Recursive Directory Brute Force Command: python3 {Tool_Dir}dirsearch/dirsearch.py -w {Small_Dirlist} -e php,exe,sh,py,html,pl -f -t 20 -u {Web_Proto}://{IP}:{Web_Port} -r 10
Entry_7: Name: Directory Brute Force CGI Description: Common Gateway Interface Brute Force Command: gobuster dir -u {Web_Proto}://{IP}:{Web_Port}/ -w /usr/share/seclists/Discovery/Web-Content/CGIs.txt -s 200
Entry_8:
Name: Nmap Web Vuln Scan
Description: Tailored Nmap Scan for web Vulnerabilities
Command: nmap -vv –reason -Pn -sV -p {Web_Port} –script=banner,(http* or ssl*) and not (brute or broadcast or dos or external or http-slowloris* or fuzzer) {IP}
Entry_9: Name: Drupal Description: Drupal Enumeration Notes Note: | git clone https://github.com/immunIT/drupwn.git for low hanging fruit and git clone https://github.com/droope/droopescan.git for deeper enumeration
Entry_10: Name: WordPress Description: WordPress Enumeration with WPScan Command: | ?What is the location of the wp-login.php? Example: /Yeet/cannon/wp-login.php wpscan –url {Web_Proto}://{IP}{1} –enumerate ap,at,cb,dbe && wpscan –url {Web_Proto}://{IP}{1} –enumerate u,tt,t,vp –passwords {Big_Passwordlist} -e
Entry_11: Name: WordPress Hydra Brute Force Description: Need User (admin is default) Command: hydra -l admin -P {Big_Passwordlist} {IP} -V http-form-post ‘/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log In&testcookie=1:S=Location’
Entry_12: Name: Ffuf Vhost Description: Simple Scan with Ffuf for discovering additional vhosts Command: ffuf -w {Subdomain_List}:FUZZ -u {Web_Proto}://{Domain_Name} -H “Host:FUZZ.{Domain_Name}” -c -mc all {Ffuf_Filters}
</details>
## 参考资料
- [https://github.com/panchocosil/burp-js-linkfinder-enhanced](https://github.com/panchocosil/burp-js-linkfinder-enhanced)
> [!TIP]
> 学习和实践 AWS 黑客技术:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> 学习和实践 GCP 黑客技术:<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
> 学习和实践 Azure 黑客技术:<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>支持 HackTricks</summary>
>
> - 查看 [**订阅计划**](https://github.com/sponsors/carlospolop)!
> - **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**Telegram 群组**](https://t.me/peass) 或 **在** **Twitter** 🐦 **上关注我们** [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub 仓库提交 PR 来分享黑客技巧。
>
> </details>


