逻辑漏洞百出/逻辑漏洞什么意思-小白漏洞知识点
0x01 测试内容
测试系统是否存在设计缺陷、逻辑错误漏洞,如支付漏洞、业务流程绕过、业务功能缺陷、短信轰炸、任意用户密码重置等。
0x02 漏洞原理
什么是设计缺陷/逻辑漏洞?
设计缺陷/逻辑漏洞是指由于程序逻辑不严谨或逻辑太复杂,导致一些逻辑分支不能正常处理或处理错误。攻击者利用业务/功能上的设计缺陷,获取敏感信息或破坏业务的完整性。
设计缺陷/逻辑漏洞产生的主要原因
一个系统功能太多后,程序开发人员难以思考全面,只考虑了常规的操作流程(比如,在A情况,会出现B,那么执行C即可),对某些地方可能有遗漏,或者未能正确处理,从而导致逻辑漏洞。逻辑漏洞也可以说是程序开发人员的思路错误、程序开发人员的逻辑存在错误。
一般常出现在什么场景?
用户注册、用户登录、验证码获取、权限鉴定、交易支付、修改个人资料等。
为什么逻辑漏洞不好防范?
设计缺陷/逻辑漏洞是非常隐蔽的,它不像SQL注入、XSS、文件上传、命令执行等,有鲜明的表示,自动化、半自动化扫描器可以定义一系列规则识别出这些漏洞,而逻辑漏洞一般出现在功能、业务流程中,每个漏洞的出现都有一定的独特性,很难复制或者通过规则脚本、漏扫工具精准识别。攻击者利用代码逻辑上的缺陷,利用合法流量进行攻击,也没有防御标准。
0x03 代码示例
.4支付逻辑漏洞。版本存在订单支付逻辑漏洞,提交订单后可将商品的数量修改为负数,然后选择站内支付,可以成功提交订单。
lib//的dobuy方法,dobuy函数内部对提交的数据过滤不严格,接着调用第51行 $ += (($_POST['qty'][$i]) * $price) * 1代码。
()函数的作用是获取变量的整数值,这里的qty代表数量,后续代码没有对qty进行过滤,如果其值为负出,那系统最后计算得到的金额就为负,导致漏洞的产生。
//订单处理 function dobuy(){ self::is_login(); if (!$_POST) { exit(); } if (!is_array($_POST['id'])) { $this->error('您的购物为空!'); exit(); } if ($_POST['realname'] == '' || $_POST['tel'] == '') { $this->error('收货人信息为空!'); exit(); } $trade_type = (int)$_POST['trade_type']; $iscart = (int)$_POST['iscart']; $group_trade_no = "GB" . time() . "-" . $_SESSION['dami_uid']; if ($iscart == 1) { import('@.ORG.Cart'); $cart = new Cart(); $cart->destroy(); } //过滤可能出现的xss $_POST = array_map('remove_xss', $_POST); $trade = M('member_trade'); if (C('TOKEN_ON') && !$trade->autoCheckToken($_POST)) { $this->error(L('_TOKEN_ERROR_')); }//防止乱提交表单 //循环出购物车 写进数据库 if ($trade_type == 1) { //...... } else if ($trade_type == 2) { //...... //接着会执行这段逻辑 } else 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'] . '
'; } } //扣款 M('member')->setDec('money', 'id=' . $_SESSION['dami_uid'], $total_fee); if (intval(C('MAIL_TRADE')) == 1) { $config = F('basic', '', './Web/Conf/'); $user_name = $config[sitetitle] . '管理员'; $subject = $config[sitetitle] . '订单提醒'; $bodyurl = '下单时间:' . date('Y-m-d H:i:s', time()) . '
会员编号:' . $_SESSION['dami_uid'] . '
姓名:' . $_POST['realname'] . '
订单号:' . $group_trade_no . '
付款方式:站内扣款
订购物件:
' . $title . '
总数量:' . $total_num . '
总金额:' . $total_fee . '元'; $sendto_email = C('MAIL_TOADMIN'); $email_port = C('MAIL_PORT'); send_mail($sendto_email, $user_name, $subject, $bodyurl, $email_port); } $this->assign('group_trade_no', $group_trade_no); $this->display('buysuccess'); } else { $this->error('交易方式不确定!'); exit(); } }
0x04 测试过程测试案例1
短信轰炸
打开APP,点击【手机验证码登录】,输入手机号码,截取数据包。
重放数据包,可无限制发送短信,造成短信轰炸漏洞。
测试案例2
任意用户密码重置
打开APP,点击【忘记密码】,输入手机号、密码,点击【获取验证码】后截取数据包。
在返回包中获取明文验证码。
输入验证码,提交。密码重置成功。
测试案例3
.6.3.2订单金额任意修改漏洞。攻击者利用业务逻辑层的应用安全问题,在提交订单时抓取数据包并修改,以及对订单的数量进行任意修改。
进入网站,登录用户,查看账户余额为100元。
点击精选产品模块,任意选一款商品,数量随便选,点击购买,抓取请求包。
将请求包中的值改为负数,放包。
页面自动跳转至支付页面,订购总价变为负数。
~
网络安全学习,我们一起交流
~