逻辑漏洞(业务支付逻辑漏洞)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 总结
业务支付漏洞的产生通常源于在编写支付逻辑时的不严谨。这些漏洞可能是因为开发者未能充分考虑各种支付场景、未进行全面的输入验证、或者对支付过程中的边界条件和异常情况缺乏考虑。一旦这些漏洞被利用,可能会造成巨大的损失。