作为一名日常喜欢点外卖、又喜欢吃汉堡的苦逼大学生,我最近在某汉堡连锁店的点餐小程序里,发现了一个支付逻辑漏洞,可以实现0元购。当然,作为有职业道德修养的大学生,发现后第一时间上报了平台并协助修复。
在开始之前,我们先看看正常的支付流程是怎么走的。一般来说餐饮系统是这个点单逻辑:
1. 选择商品(如汉堡+可乐套餐)→ 点击"立即购买"
2. 填写收货地址 / 选择到店自提
3. 进入订单确认页,显示总价、优惠券、实付金额等
4. 点击"去支付"→ 跳转至第三方支付平台(如微信 / 支付宝)
5. 支付完成后跳转回 App,订单状态变为"待接单"或"已支付"
在常规的支付逻辑中,后端应该对以下关键字段进行强校验:
1. 商品价格必须由后台计算,不可信任前端提交的数据
2. 支付状态必须依赖第三方支付平台的真实回调
3. 优惠券使用逻辑必须绑定用户、状态、过期时间,并严格控制数量
但很多时候,开发为了"快速上线",往往在这些地方埋下隐患……这时候就是我们趁虚而入的时候喽,也就是在计算商品价格,或者是提交dopay的时候尝试改敏感字段。
通常来说敏感字段有这些:
productid 商品id
price 价格
count 数量
discount 折扣
couponPrice 优惠券
payType 支付方式
payStatus支付状态
finalAmount 最终价格
经过分析这个小程序计算购物车价格都是在后端,也做了价格的校验。数据包直接发过去商品id 购物车id ,然后计算。所以修改数据包价格是没有用的
关键在于提交支付的时候有一个submit接口
{"memberId":"2336182439538851840",
"openId":"",
"storeId":"1162731767332864",
"orderFrom":1,
"orderType":2,
"userCouponId":"",
"couponCode":"",
"paymentCode":1,
"receiverName":"磊",
"receiverMobile":"",
"receiverAddress":"",
"remark":"",
"latitude":,
"longitude":,
"carList":
[{"spuId":"1259209795738820608",
"skuId":"1259209795780763648",
"flavorList":[],
"condimentsList":[],
"copies":1,
"setmealType":2,
"singleList":
[
{"1264812338473361408":1},
{"1264812338800517120":1},
{"1264812339119284224":1},
{"1264812339446439936":1}],
"openId":"oHVqn65MyJWgPAgf_z7CudMd_cp0","isPurchase":0}
],
"takeAwayTel":"",
"appointmentTime":"立即取餐",
"mainId":"undefined"}
然后就是dopay接口
这里惯性思维肯定直接尝试直接修改dopay接口的价格,或者是同时下两个订单一个低一个高,直接改订单号替换支付,好吧都无果,全部都做了校验。然后这时候回头看Submit接口,有两个敏感字段 :1.userCouponid 2.couponCode 那么有没有可能submit提交这里,可以伪造一个优惠券,然后提交上去,让服务端计算价格呢?
接着去burp里面找到了一个myCouponList接口,这里正好对应上了submit里面的信息可以填一下,但是这是我自己的优惠券,没什么卵用啊
接着找到了一个counponList的接口,发送的数据包里有一个counponPrice字段
根据前面的推测,submit接口可能是提交优惠券然后在后端计算价格。那么我们接着在submit的接口构造这个字段couponPrice为6,然后couponCode和ID直接置空试试
成功了!dopay接口变成了11.5,然后发起了微信支付
后续尝试可以修改CouponPrice字段任意修改优惠券金额,最终实现0元购。这里我为什么没有0元购呢,因为我真的买了,0元购问题太明显....
附支付逻辑漏洞一些思路:
|
|
---|---|
|
|
|
0.01 、绕过金额判断 |
|
-10.0 做付款金额,若系统未验证,可导致反向 |
|
|
|
|
|
|
原文始发于微信公众号(Z2O安全攻防):汉堡白吃?某连锁餐饮 App 竟藏0元购漏洞!
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论