記一次某CMS代碼審計
VSole2022-11-07 09:52:41
前言
無意中瀏覽到某小眾OA官網且可以下載到源碼,隨機審計一波,最后成功Getshell,大佬勿噴
目錄結構

環境搭建
WIN11 + PhpStudy(Mysql) + Redis + IDEA(Tomcat 8.0)
將sql文件導入到phpstudy(Mysql)中,同時啟動Redis服務,配置好數據庫環境


采用白+黑進行審計,從功能點出發,在個人資料處圖像可以進行上傳

開始抓包進行文件上傳,后綴和文件內容均沒有做校驗,且返回上傳的路徑和文件名,本以為可以直接getshell,但卻無法解析,且該文件并沒有落地



代碼審計
根據數據包的路徑(/func/upload/uploadImages)直接搜索路由,成功找到上傳函數

首先會對db的值進行判斷,根據db的值來決定上傳文件的保存方式

初始上傳的時候,db=1,而if的GlobalConstant.FILE_UPLOADER_SAVE_FILE=0,故直接進入到else if

新的文件名 = 上傳時間 + 10位隨機數 + 原始上傳文件的后綴名
String extend = FileUtils.getExtend(fileName);// 獲取文件擴展名String noextfilename = DateUtils.getDataString(DateUtils.SDF_YYYYMMDDHHMMSS) + StringUtil.random(10);//自定義文件名稱String myfilename= noextfilename+"."+extend;//自定義文件名稱

文件存儲在數據庫中,并將文件名通過map保存,最后返回在數據包中



db可控,在上傳的時候,將db=1改為db=0,進入到if

會創建新的上傳目錄,新的目錄 = Web根目錄 + upload + 上傳時間(年月日),若不存在則進行新建
String realPath = request.getSession().getServletContext().getRealPath("/") + "/upload/" + strYYYYMMDD + "/";// 文件的硬盤真實路徑String path = "upload/" + strYYYYMMDD + "/";File file = new File(realPath); if (!file.exists()) { file.mkdirs();// 創建根目錄}

新的文件名的命名方式跟else if基本一致,在獲取文件的后綴名的時候,并未進行檢查和過濾,直接進行拼接,從而造成了文件上傳漏洞

最后將上傳文件內容直接復制到新創建的文件
FileCopyUtils.copy(mf.getBytes(), savefile);


最后通過map進行存儲,且將文件上傳路徑和文件名分別存儲在 filePath、saveName
Map<String, Object> map = new HashMap<String, Object>();map.put("filePath", GlobalConstant.CONFIG_FILE_SAVE_DB_URL + myfilename);map.put("saveName", noextfilename);

上傳回顯的Jsp Webshell,將db在上傳的時候改為db=0,成功上傳,可執行命令


VSole
網絡安全專家