上傳偽技術~很多人都以為判斷了尾碼,判斷了ContentType,判斷了標頭檔就真的安全了。是嗎?

來源:互聯網
上載者:User

標籤:

今天群裡有人聊圖片上傳,簡單說下自己的經驗

0.如果你的方法裡面是有指定路徑的,記得一定要過濾../,比如你把 aa檔案夾設定了許可權,一些類似於exe,asp,php之類的檔案不能執行,那麼如果我在傳路徑的時候,前面加了一個../呢,這樣這種伺服器端的限制就跳過了。(DJ音樂站基本上都有這個問題,以及用某編輯器的同志)

1.常用方法:這種就是根據尾碼判斷是否是圖片檔案,需要注意的是這種格式:檔案:1.asp;.jpg  1.asp%01.jpg  目錄: 1.jpg/1.asp 1.jpg/1.php 等等,IIS和Nginx部分版本是有解析漏洞的(不要用檔案原有名稱,eg:1.asp.jpg=》去尾碼後的名字就是1.asp)

/// <summary>        /// 圖片上傳        /// </summary>        /// <param name="file"></param>        /// <returns></returns>        public JsonResult UploadA(HttpPostedFileBase file)        {            if (file == null) { return Json(new { status = false, msg = "圖片提交失敗" }); }            if (file.ContentLength > 10485760) { return Json(new { status = false, msg = "檔案10M以內" }); }            string filterStr = ".gif,.jpg,.jpeg,.bmp,.png";            string fileExt = Path.GetExtension(file.FileName).ToLower();            if (!filterStr.Contains(fileExt)) { return Json(new { status = false, msg = "圖片格式不對" }); }            //todo: md5判斷一下檔案是否已經上傳過,如果已經上傳直接返回 return Json(new { status = true, msg = sqlPath });            string path = string.Format("{0}/{1}", "/lotFiles", DateTime.Now.ToString("yyyy-MM-dd"));            string fileName = string.Format("{0}{1}", Guid.NewGuid().ToString("N"), fileExt);            string sqlPath = string.Format("{0}/{1}", path, fileName);            string dirPath = Request.MapPath(path);            if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); }            try            {                //todo:縮圖                file.SaveAs(Path.Combine(dirPath, fileName));                //todo: 未來寫存資料庫的Code            }            catch { return Json(new { status = false, msg = "圖片儲存失敗" }); }            return Json(new { status = true, msg = sqlPath });        }

2.Context-Type的方法(很多人說這個安全性比上一個高。。。。。呃,也許吧,上面至少還有個檔案尾碼硬性判斷,contentType這玩意抓個包,本地代理一開,直接就可以串改,傳的是1.asp,你收的contextType依舊是圖片格式,最後儲存就玩完了)

/// <summary>        /// 圖片上傳        /// </summary>        /// <param name="file"></param>        /// <returns></returns>        public JsonResult UploadB(HttpPostedFileBase file)        {            if (file == null) { return Json(new { status = false, msg = "圖片提交失敗" }); }            if (file.ContentLength > 10485760) { return Json(new { status = false, msg = "檔案10M以內" }); }            //判斷檔案格式(MimeMapping)            var contentType = file.ContentType;            if (contentType == null) { return Json(new { status = false, msg = "圖片提交失敗" }); }            contentType = contentType.ToLower();            var extList = new Dictionary<string, string>() { { "image/gif", ".gif" }, { "image/jpeg", ".jpg" }, { "image/bmp", ".bmp" }, { "image/png", ".png" } };            if (!extList.ContainsKey(contentType)) { return Json(new { status = false, msg = "圖片格式不對" }); }            //todo: md5判斷一下檔案是否已經上傳過,如果已經上傳直接返回 return Json(new { status = true, msg = sqlPath });            string path = string.Format("{0}/{1}", "/lotFiles", DateTime.Now.ToString("yyyy-MM-dd"));            string fileName = string.Format("{0}{1}", Guid.NewGuid().ToString("N"), extList[contentType]);            string sqlPath = string.Format("{0}/{1}", path, fileName);            string dirPath = Request.MapPath(path);            if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); }            try            {                //todo:縮圖                file.SaveAs(Path.Combine(dirPath, fileName));                //todo: 未來寫存資料庫的Code            }            catch { return Json(new { status = false, msg = "圖片儲存失敗" }); }            return Json(new { status = true, msg = sqlPath });        }

如果非要用這個,建議和第一個一起用

3.標頭檔判斷,很多人都以為這是最終方案。。。。。。呃,也許吧,不過如果你是4.5以及以後也許就可以這樣理解了~~

先貼代碼:

/*標頭檔參考:(我自己測是如有偏差請聯絡我)
7790:exe,dll

5666:psd
6677:bmp
7173:gif
13780:png
255216:jpg,jpeg

8297:rar
55122:7z
8075:docx,xlsx,pptx,vsdx,mmap,xmind,“zip”
208207:doc,xls,ppt,mpp,vsd
 */

    /// <summary>    /// 判斷副檔名是否是指定類型---預設是判斷圖片格式,符合返回true    /// eg:file,"7173", "255216", "6677", "13780" //gif  //jpg  //bmp //png    /// </summary>    /// <param name="stream">檔案流</param>    /// <param name="fileTypes">副檔名</param>    /// <returns></returns>    public static bool CheckingExt(this Stream stream, params string[] fileTypes)    {        if (fileTypes.Length == 0) { fileTypes = new string[] { "7173", "255216", "6677", "13780" }; }        bool result = false;        string fileclass = "";        #region 讀取頭兩個位元組        using (stream)        {            using (var reader = new BinaryReader(stream))            {                byte[] buff = new byte[2];                try                {                    //讀取每個檔案的頭兩個位元組                    reader.Read(buff, 0, 2);                    fileclass = buff[0].ToString() + buff[1].ToString();                }                catch (System.Exception ex) { return false; }            }        }        #endregion        #region 校正        for (int i = 0; i < fileTypes.Length; i++)        {            if (fileclass == fileTypes[i])            {                result = true;                break;            }        }        #endregion        return result;    }

 

        /// <summary>        /// 圖片上傳(理論上需要二次渲染片,微軟Save的時候有應該有一定的驗證[我把含有一句話木馬的圖片上傳,最後會返回一張空圖片])        /// </summary>        /// <returns></returns>        public JsonResult UploadC(HttpPostedFileBase file)        {            if (file == null) { return Json(new { status = false, msg = "圖片提交失敗" }); }            if (file.ContentLength > 10485760) { return Json(new { status = false, msg = "檔案10M以內" }); }            string filterStr = ".gif,.jpg,.jpeg,.bmp,.png";            string fileExt = Path.GetExtension(file.FileName).ToLower();            if (!filterStr.Contains(fileExt)) { return Json(new { status = false, msg = "圖片格式不對" }); }            //防止駭客惡意繞過,標頭檔判斷檔案尾碼            if (!file.InputStream.CheckingExt())            {                //todo:一次危險記錄                return Json(new { status = false, msg = "圖片格式不對" });            }            //todo: md5判斷一下檔案是否已經上傳過,如果已經上傳直接返回 return Json(new { status = true, msg = sqlPath });            string path = string.Format("{0}/{1}", "/lotFiles", DateTime.Now.ToString("yyyy-MM-dd"));            string fileName = string.Format("{0}{1}", Guid.NewGuid().ToString("N"), fileExt);            string sqlPath = string.Format("{0}/{1}", path, fileName);            string dirPath = Request.MapPath(path);            if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); }            try            {                //todo:縮圖 +  浮水印                file.SaveAs(Path.Combine(dirPath, fileName));                //todo: 未來寫存資料庫的Code            }            catch { return Json(new { status = false, msg = "圖片儲存失敗" }); }            return Json(new { status = true, msg = sqlPath });        }

其實這個很好欺騙的,好幾種方法,簡單說2種:

第1個,用Copy命令

產生了一句話圖片木馬

第2個,用edjpgcom 開啟一張圖片就可以直接插入一句話木馬了

圖片跟之前看起來沒什麼不同的

WinHex看看~

上傳測試

成功上傳了

 

有人說把圖片另存新檔其他格式就能消除一句話木馬。。。。。呃,好吧,你可以這樣理解~看圖:

 

滲透的時候一般遇到這種圖片上傳後再二次渲染的,一般直接放棄,因為內部的一句話已經不存在了

至於二次渲染是什麼鬼,可以先自行研究會,先睡了~~~

 

上傳偽技術~很多人都以為判斷了尾碼,判斷了ContentType,判斷了標頭檔就真的安全了。是嗎?

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.