声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任。
注公众号,设置为星标,不定期有宠粉福利
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
Webpack 特征
# 命名块模式
[name]~[hash].js
chunk-[id]-[hash].js
async~[name].[hash].js
# 特殊文件
webpack-runtime*.js
webpack-jsonp*.js
# 实际生产环境示例
main.3d8f2a4c.js
app-bundle-1a2b3c4d.js
-
Vite 特征
# 现代打包模式
assets/index-[hash].js
assets/[name]-[hash].js
assets/[hash].js
# 预构建依赖
_vue-deps-*.js
_react-deps-*.js
# 实际生产环境示例
_vue-deps-a1b2c3d4.js
_react-deps.5e6f7g8h.js
-
Rollup特征
# 哈希模式
bundle-[hash].js
chunk-[hash].js
[hash:8].js
# 特殊模式
dynamic-import-*.js
# 实际生产环境示例
bundle-a1b2c3d4.js
main.5e6f7g8h.min.js
app-9i8j7k6l.js
3、拉取全量js
由于打包通常会将整站的页面路径和api一起打包,利用此特点,可以拉取全站的api信息,即使不登录系统,也可以了解到登录后接口,页面等情况。针对收集到的页面和api进一步开展未授权、sql注入、账号口令硬编码等漏洞挖掘。
技巧-重点关注以下情况:
注意带有`chunk`、`bundle`、`main`等名字的JS文件(通常是核心文件),可以拉取核心文件里边的异步JS文件,进一步分析。
注意`sourcemap`文件(`.map`结尾),它能还原原始代码,进一步分析原始代码,进而提取敏感信息。
-
webpack提取全量js的方法
有现成的工具,下载即可使用。
Packer-Fuzzer:https://github.com/rtcatc/Packer-Fuzzer。此工具误报率较高。
jjjjjjjjjjjjjs:https://github.com/ttstormxx/jjjjjjjjjjjjjs
-
vite拉取全量js的方法
无现成的工具,实际使用可根据以下代码小改。
import requests
from bs4 import BeautifulSoup
import re
def extract_vite_js(base_url):
response = requests.get(base_url)
soup = BeautifulSoup(response.text, 'html.parser')
# 1. 提取主入口 JS(含 Vite 热更新逻辑)
main_js = [script['src'] for script in soup.find_all('script', src=True)
if 'vite' in script.get('src', '')]
# 2. 捕获动态导入的 Chunk(如 /_vite/deps/*.js)
chunk_pattern = re.compile(r'import("([^"]+.js)")')
chunks = set(chunk_pattern.findall(response.text))
# 3. 下载所有文件
for js in main_js + list(chunks):
js_url = urljoin(base_url, js)
content = requests.get(js_url).text
with open(js.split('/')[-1], 'w') as f:
f.write(content)
-
Rollup提取全量js方法
import re
import argparse
from pathlib import Path
def analyze_js(file_path):
"""分析JS文件中的敏感信息"""
results = {"urls": [], "keys": [], "credentials": []}
try:
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
# 提取URL
results["urls"] = re.findall(r'https?://[^s"']+', content)
results["urls"] += re.findall(r'['"`](/[^s"']+?)['"`]', content)
# 提取密钥
results["keys"] = re.findall(
r'(?:api[_-]?key|secret[_-]?key|access[_-]?key)s*[=:]s*['"`]([^'"`]{10,})['"`]',
content, re.IGNORECASE
)
# 提取账号密码
creds = re.findall(
r'b(?:user|login|account|auth)s*[=:]s*['"`]([^'"`]+)['"`].*?'
r'b(?:pass|pwd|credential)s*[=:]s*['"`]([^'"`]{6,})['"`]',
content, re.IGNORECASE | re.DOTALL
)
results["credentials"] = [f"user={u}, pass={p}" for u, p in creds]
# 其他敏感信息
results["emails"] = re.findall(r'b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Z|a-z]{2,}b', content)
return results
except Exception as e:
return {"error": str(e)}
def main():
parser = argparse.ArgumentParser(description='JS敏感信息分析工具')
parser.add_argument('path', help='JS文件或目录路径')
args = parser.parse_args()
path = Path(args.path)
if path.is_file():
results = {str(path): analyze_js(path)}
elif path.is_dir():
results = {}
for js_file in path.glob('**/*.js'):
results[str(js_file)] = analyze_js(js_file)
else:
print(f"无效路径: {path}")
return
# 打印结果
for file, data in results.items():
print(f"n 文件: {file}")
for category, items in data.items():
if items:
print(f"n {category.upper()}:")
for item in items:
print(f" - {item}")
if __name__ == "__main__":
main()
原文始发于微信公众号(锐鉴安全):常见JS打包工具安全分析
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论