邏輯漏洞(業務支付邏輯漏洞)dami CMS
0x01 業務邏輯簡介
業務邏輯指的是一個系統或應用程序中的實際業務規則和流程。它描述了如何處理特定的業務需求、數據和操作。業務邏輯通常是根據特定行業或組織的需求而設計的。
在軟件開發中,業務邏輯是指應用程序處理數據的方式、進行計算和決策的規則,以及用戶執行特定操作時系統的響應方式。這些規則和流程定義了系統的行為,并確保系統能夠按照預期的方式工作。
舉例來說,對于在線購物系統,業務邏輯包括但不限于以下內容:
- 用戶添加商品到購物車后如何計算總價;
- 用戶下單后的支付和物流處理流程;
- 管理員如何管理商品庫存和價格;
- 用戶的個人信息如何存儲和保護。
業務邏輯通常在軟件開發過程中被轉化為代碼,實現特定的功能和需求。在安全方面,了解業務邏輯對于發現潛在的安全漏洞和保護系統安全也非常重要。
0x02 dami靶場
dami cms 靶場是一個使用thinkphp2.1版框架搭設的網站,它是thinkphp的早期版本,目前也很少在使用。
ThinkPHP是一個基于PHP語言的開源Web應用框架,采用MVC(Model-View-Controller)設計模式,有助于更好地組織應用程序代碼。它提供了豐富的工具和函數庫,簡化了開發流程,包括強大的路由功能、模板引擎和ORM支持。
首先通過注冊頁面,多注冊幾個賬號,用于測試越權。
漏洞 一
? 驗證碼驗證漏洞,未設置過期時間,導致驗證碼一直有效,會被暴力破解利用。
- 經測試,驗證碼機制為頁面刷新才會重新生成新的驗證碼
漏洞 二
支付漏洞,訂單數量未嚴格限制,導致可通過抓包修改負數,導致支付漏洞
支付選項中,分別為 支付寶支付、貨到付款、站內支付,選擇站內支付,點擊購買后,進行抓包。
發現前端使用POST的方式,發送的訂單信息給后端進行處理。發送的內容經過了URL編碼,通過解碼了解到發送為以下內容
id[]=69
: 一個 ID 列表,包含一個 ID 為 69 的條目。pic[]=\/Public\/Uploads\/thumb\/thumb_1393206337.jpg
: 圖片列表,指向一個圖片路徑/Public/Uploads/thumb/thumb_1393206337.jpg
。name[]=大米CMS手機開發專版
: 名稱列表,包含一個名稱為“大米CMS手機開發專版”的條目。gtype[]=灰色
: 類型列表,包含一個類型為“灰色”的條目。qty[]=1
: 數量列表,包含一個數量為 1 的條目。price[]=5400
: 價格列表,包含一個價格為 5400 的條目。realname=123
: 真實姓名為 “123”。tel=123
: 電話號碼為 “123”。province=寧夏
、city=銀川市
、area=市轄區
: 地址信息,包括省份為“寧夏”,城市為“銀川市”,地區為“市轄區”。address=
: 地址為空。trade_type=2
: 交易類型為 2。iscart=0
: 是否在購物車中為 0。__hash__=7fe310a6298f63572cae4f0f818eafd9
: 可能是用于驗證或身份驗證的哈希值。
在支付漏洞中,黑客最想干的事情就是白嫖,所以在這一串信息中,我們著重關注與金錢相關的的內容,那么我們可以嘗試去修改qty[]
和price[]
兩條信息,來嘗試修改數量或金額來達到白嫖的目的。
由于我們注冊的賬號并沒有錢,所以我修改qty[]
為-1,來嘗試購買。
通過回顯發現,已經成功下單,通過站內查詢,我購買了一個產品,網站又給了我5400元,這是又白嫖,又拿錢。
現在賬號有錢了,繼續嘗試,查看price[]
在金額參數中是否還存在漏洞。
將price[]
參數值改為1,回顯頁面顯示余額不足,應該是做了相對應的限制,繼續嘗試。
多次嘗試后,任然不行,price[]
參數應該是后端已經根據id[]
鎖定了。所信把qty[]
改為-100,price[]
改為16000,回顯訂單提交成功,但是訂單數量應該變了,金額應該不會有變化。
與我猜想是一樣,價格金額仍然是6000元,數量卻變成是-100,而我的余額變成60萬5千400元,由此也可以看出業務邏輯漏洞的可怕之處,空手套白狼的一把好手!!!
代碼分析
ThinkPHP采用了自己的一套約定俗成的文件架構,這種方式有別于一些其他框架。
在ThinkPHP中,index.php
文件是整個應用的入口文件,它通常放置在Web服務器的根目錄中。通過這個入口文件,整個應用被啟動并初始化。
通常,ThinkPHP的核心代碼會放置在/lib/
目錄下。在這個目錄中,包含了各種類文件,這些文件定義了框架的核心功能和組件。這些類文件包括路由處理、模板引擎、數據庫操作、安全特性等。
在整個應用的生命周期中,index.php
文件會加載這些核心類文件,并根據請求的路由信息調用相應的控制器和方法。這種架構隱藏了很多細節,使得開發者可以更專注于業務邏輯,同時框架會自動處理很多底層工作。
此次漏洞挖掘我們是經過,www.dami.me/index.php?s=/Member/dobuy.html
,那么我們就應該從Web文件下去找類文件/Member
下去找dobuy()
方法。
if($trade_type ==3){
$title='';
$total_fee =0;
$total_num =0;
for($i=0;$i<count($_POST['id']);$i++){
$price = (float)M('article')->where('aid='.intval($_POST['id'][$i]))->getField('price');
if(!is_numeric($_POST['id'][$i]) || !is_numeric($_POST['price'][$i]) || !is_numeric($_POST['qty'][$i])){continue;}
$total_fee += (intval($_POST['qty'][$i]) * $price)*1;
}
$have_money = M('member')->where('id='.$_SESSION['dami_uid'])->getField('money');
if($have_money < $total_fee){
$this->assign('jumpUrl',U('Member/chongzhi'));
$this->error('您的余額不足,請充值!');exit();
}
for($i=0;$i<count($_POST['id']);$i++){
if(!is_numeric($_POST['id'][$i]) || !is_numeric($_POST['price'][$i]) || !is_numeric($_POST['qty'][$i])){continue;}$data['gid'] = $_POST['id'][$i];$data['uid'] = $_SESSION['dami_uid']; $data['price'] = (float)M('article')->where('aid='.$data['gid'])->getField('price');//必須$data['province'] = $_POST['province'];$data['city'] = $_POST['city'];$data['area'] = $_POST['area'];$data['sh_name'] = $_POST['realname'];$data['sh_tel'] = $_POST['tel'];$data['address'] = $_POST['address'];$data['group_trade_no'] = $group_trade_no;$data['out_trade_no'] = "DB".time()."-".$_SESSION['dami_uid']; $data['servial'] = $_POST['gtype'][$i];$data['status'] = 1;//已付款等待發貨$data['trade_type'] = 3;$data['addtime'] = time();$data['num'] = (int)$_POST['qty'][$i];$total_num += $data['num'];$trade->add($data);if(strlen($title)<400){$title .= $_POST['name'][$i]." 數量:".$data['num'].' 單價:'.$data['price'].'<br>';}
}
在第6行的代碼中,可以看到價格并不是由前端頁面傳入到$data
變量中,而是從名為 article
的數據庫表中,根據指定條件(aid
等于 $data['gid']
),獲取對應記錄的 price
字段值,并將其轉換為浮點數類型,最后存儲在 $data['price']
中。所以我們在BP中修改price
沒有任何效果。
然而在第8行代碼中,qty
只做了轉換為整型的操作,驗證的不夠驗證,所以導致了該漏洞的生成.
在初步的代碼審計后,感覺該靶場應該還存在很多漏洞,在日后的博客更新中在慢慢挖掘。
0x03 總結
業務支付漏洞的產生通常源于在編寫支付邏輯時的不嚴謹。這些漏洞可能是因為開發者未能充分考慮各種支付場景、未進行全面的輸入驗證、或者對支付過程中的邊界條件和異常情況缺乏考慮。一旦這些漏洞被利用,可能會造成巨大的損失。