逻辑漏洞是指由于程序逻辑输入管控不严或者逻辑太复杂,导致程序不能够正常处理或处理错误,逻辑漏洞根据功能需求的不同产生的漏洞方式也不同。一般出现在网站程序的登录注册、密码找回、验证方式、信息查看、交易支付金额等地方。
这类漏洞不同于常见WEB漏洞,常见WEB漏洞都可以总结为一定的范式,而逻辑漏洞不行
逻辑漏洞出现的原因也是有很多种,需要有一定个人经验积累才能在代码审计过程中发现此类漏洞
挖掘思路
首先将所有逻辑漏洞的问题分为前端和后端两个部分,先测试绕过前端规则限制再测试绕过后端规则限制,一般情况下只要能够突破原有规则限制的都就可以算是漏洞。
挖掘逻辑漏洞总体步骤分为以下三步:
- 明确业务逻辑流程,根据业务需求的特点,有针对性的进行测试。
- 寻找流程中可以被操控的环节,分析可被操控环节中可能产生的逻辑问题。
- 珠宝修改参数触发逻辑问题,重放包对比结果差异。
业务逻辑漏洞
登录模块
- 暴力破解
- 任意用户/密码登陆
- 短信/邮箱轰炸
- 验证码绕过/爆破/重放/回传
- 用户名/手机号枚举
- 越权登陆(例如修改数据包中用户ID)
- 账号权限绕过(越权)
- Cookie伪造
- 用户空密码登陆
注册模块
- 前端验证绕过
- 用户任意/批量注册
- 恶意验证注册账户
- 账户重复注册
- 用户名/绑定手机号枚举
- 注册信息插入XSS
- 短信/邮箱轰炸
- 验证码绕过/爆破/重放/回传
- 其他验证机制绕过
密码找回
- 任意/批量用户密码重置
- 任意邮箱/手机号验证(验证码与绑定用户未统一验证)
- 用户绑定手机号枚举
- 新密码劫持
- 短信验证码劫持/绕过/回传/爆破/重放
- 用户邮箱劫持/篡改
- 其他验证机制绕过
购买支付/充值
- 商品金额/数量篡改
- 替换支付模块
- 交易信息泄露
- 虚假充值金额
- 充值账户/金额/数量篡改
- 支付验证绕过
- 整数溢出,int最大值为2147483647
- 修改本地JS或服务端返回的数据包中的关键值
个人资料
- 手机号/用户/邮箱枚举
- 修改个人资料插入XSS
- 邮箱/用户/手机号篡改
- 用户信息遍历/泄露
- 越权修改他人账户资料
抽奖/活动
- 任意抽奖
- 盗刷奖品/积分
- 抽奖积分/次数篡改
- 并发抽奖
- 邀请码XSS(验证码URL可能包含用户名,可将用户名修改为XSS代码)
代金券/优惠券
- 批量刷取代金券/优惠券
- 更改代金券金额/数量
- 更改优惠券数量
- 并发逻辑漏洞(burp批量获取优惠劵等)
订单
- 订单信息遍历/泄露
- 订单信息泄露导致用户信息泄露
- 越权修改/删除他人订单
账户
- 账户验证绕过
- 账户金额篡改
- 账户绑定手机号绕过
- 账户第三方账户绑定绕过
会员系统
- 用户越权操作访问
- 个人资料信息遍历/泄露
- 修改个人信息头像上传任意文件
- 如果遇到xlsx/docx,可能存在XXE,上传恶意文档盲测
- 修改个人信息页面插入XSS
传输过程
- POST/Cookie注入
- cookie劫持
- 修改信息处无session/token导致CSRF
- 明文传输账号密码
评论模块
- POST注入
- 无session/token导致CSRF
- 评论时插入XSS
- 遍历用户ID导致用户信息泄露
- 恶意批量刷评论数量
第三方系统
- 第三方系统未授权访问
- 第三方账户信息遍历
- 第三方账户越权访问
- 第三方账户信息泄露
- 第三方应用版本漏洞
验证码安全
- 验证码参数删除绕过
- 验证码生成规律预测
- 验证码图像内容可被工具识别
- 验证码长期不失效,进行爆破
- 验证码回显到页面或者数据包中
- 单个验证码可多次重复利用
- 短信验证码与手机号未统一验证
- 短信验证码未对单个手机号发送次数进行限制
- 短信验证码未做发送时间限制,导致短信轰炸
- 可能存在万能验证码
接口调用
-
未授权访问敏感数据接口
-
短信api接口泄露被恶意调用
-
数据库接口泄露,导致数据可被恶意操作
逻辑漏洞利用
验证码
万能验证码:
程序员在开发验证码模块时,为了方便调用验证码验证功能是否完善,故意设置了几个万能的验证码作为测试数据。在开发结束后由于程序员的疏忽,没有删除该测试验证码数据从而导致该漏洞的产生。
验证码回传:
通过抓包的方式,可以看到验证码内容回显在了数据包中;或者通过查看网页源代码可以看到验证码中的内容,导致正确验证码可以被直接读取利用到。
删除验证码绕过:
通过抓包将验证码的值删除或者直接删除验证码参数,然后将修改后的数据包进行重放导致验证码验证被绕过。
验证码爆破:
此处验证码爆破通常是指手机短信验证的方式,由于没有对输入同一个验证码的次数做限制,并且验证码的内容太简单,例如4位或者6位的纯数字组成。可以通过Burp的Intruder模块对验证码内容进行爆破,直到匹配到正确的验证码。
验证码重放
首先,输入错误的验证码,进行抓包重放一次,观察验证的返回的数据包内容,再用正确的验证码再进行抓包重放,对比两个数据包的差异,然后根据这些差异验证码是否失效。
然后将正确的验证码发送至Burp的Intruder模进行不断的重放,比较这些数据包是否都是正确验证码时返回的一样内容,如果数据包内容一样说明存在验证码重放的漏洞。
验证码与手机号未统一匹配
首先用自己的手机收到正确验证码,在点击注册时拦截包将手机号改为其他手机号,如果成功的话就注册了别人的手机号,这是因为后端仅验证了验证码是否是正确的而没有验证验证码是否与手机匹配。
短信轰炸
尝试不断重放发送验证码的数据包,查看手机是否在短时间内收到了多条短信,是的话则存在短信轰炸漏洞,这是因为后端没有对发送手机短信做时间/次数限制。
如果后端对短信验证码做了限制,那么可以尝试以下几种方式进行绕过:
- 删除修改cookie或者返回值,重放数据包
- 遍历参数发送数据包
- 对参数进行叠加
- 手机号后面加空格(%20)或者前面加其他的比如+86、逗号、分号、字母等
- 请求参数修改大小写,或者添加请求参数&id=1
- 多接口测试,可能登陆位置做了防护,但密码找回出没有防护
- 利用调用接口绕过短信轰炸限制
- 修改IP绕过短信轰炸限制
- 添加重复的手机号参数,重放数据包
越权操作
首先用一个账号登陆系统后,通过抓包修改用户参数,可以达到查看或者修改他人账号的目的,尽量对多接口或者多功能模块进行不断测试越权操作。同时也要多个账号登陆,分析对比这些账号数据包中的请求参数差异,通过修改这些存在差异的参数,看看是否能够达到越权操作的目的。
越权漏洞又分为平行越权,垂直越权和交叉越权。
- 平行越权:权限类型不变,权限ID改变
- 垂直越权:权限ID不变,权限类型改变
- 交叉越权:即改变ID,也改变权限
用户信息泄露
可能存在用户个人信息页面、密码找回处以及各种调用到用户信息数据的地方,通过抓包查看返回信息是否加载了一些敏感的数据信息,比如查询用户信息的时候也将用户的密码数据在数据包中回显了;或者在用户个人资料页面,通过抓包修改用户ID参数,可以通过遍历查询到其他账号的用户资料,导致用户信息泄露;
任意用户密码重置
通常发生在忘记密码处,由于系统没有严格匹配用户忘记密码时的验证方式,通过抓包修改用户参数,导致任意用户的密码都能够被重置。
比如某个忘记密码功能处采用手机号短信验证的方式来重置用户密码,如果该验证手机号没有对用户账户进行绑定,那么就可以通过输入任意手机号接收短信验证,然后就可以利用该验证码重置用户密码了。
订单金额任意修改
很多中小型的购物网站都存在订单金额任意修改漏洞。在提交订单的时候抓取数据包或者直接修改前端代码,然后对订单的金额任意修改。
经常见到的参数大多为:rmb 、value 、amount 、cash 、fee 、money 等
关于支付的逻辑漏洞这一块还有很多种思路,比如相同价格增加订单数量,相同订单数量减少产品价格,订单价格设定为负数等等。
未授权访问
有些业务的接口,因为缺少了对用户的登陆凭证的较验或者是验证存在缺陷,导致黑客可以未经授权访问这些敏感信息甚至是越权操作。
一般容易出现在文件导出下载,JSON数据页面,第三方应用页面等位置。
常见案例:
- 某电商后台主页面,直接在管理员web路径后面输入main.php之类的即可进入。
- 某航空公司订单ID枚举
- 某电子认证中心敏感文件下载
- 某站越权操作及缺陷,其主要原因是没对ID参数做cookie验证导致
实际上还有很多案例,他们都存在一个共同的特性,就是没有对用户的登陆凭证进行效验
接口无限制枚举
有些关键性的接口因为没有做验证或者其它预防机制,容易遭到枚举攻击。
常见案例:
- 某电商登陆接口无验证导致撞库
- 某招聘网验证码无限制枚举
- 某快递公司优惠券枚举
- 某电商会员卡卡号枚举
- 某超市注册用户信息获取
cookie/token设计存在缺陷
cookie的效验值过于简单。有些web对于cookie的生成过于单一或者简单,导致黑客可以对cookie的效验值进行一个枚举。或者通过修改cookie中的某个参数可以登陆其他用户,即cookie仿冒。
token一般是操作令牌,每个用户在登录系统时,服务器会为每个用户生成token令牌作为操作凭证。如果token设计太过于简单,那么可能会被破解;或者token没有设置过期的时间,使得用户token不唯一,导致用户token存在被盗用的风险。
找回密码存在设计缺陷
auth设计缺陷
经常研究逻辑漏洞的人可能会对以下URL很熟悉
www.xxx.com/resetpassword.php?id=MD5
用户修改密码时,邮箱中会收到一个含有auth的链接,在有效期内用户点击链接,即可进入重置密码环节。而大部分网站对于auth的生成都是采用rand()函数,那么这里就存在一个问题了,Windows环境下rand()最大值为32768,所以这个auth的值是可以被枚举的。
如下面这个代码可以对auth的值做一个字典。
$a=0;
for ($a=0;$a<=32768;$a++){
$b=md5($a);
echo "\r\n";
echo $b;
}
然后重置某个账号,并且对重置链接内的auth进行枚举。
签约漏洞
- 使用A手机登陆账号A打开要测试的业务,点击自动续费,支付时停留在支付界面。
- 使用B手机登陆账号A打开要测试的业务,点击自动续费,支付时停留在支付界面。
- 重复多台手机进行同样操作
- A手机点击支付进行签约
- A手机支付成功后,在第三方APP中解除自动续费
- B手机进行支付,支付成功后在第三方APP中解除自动续费
- 全部支付完成后,系统就会为你开通相应的次数,由于提前打开了支付界面,所以金额都是享受到新用户首月优惠的金额。
- 最终的效果是,一个
账户享受到了多次新用户首月优惠金额,即证明漏洞的存在。
通常这种漏洞比较容易出现在活动页面的会员优惠开通,而且要考虑到支付后要比正常购买优惠才算是漏洞。
会员升级
- 使用A手机登陆账号A,并且开通会员。开通超级会员,进入到升级页面,进行补齐差价开通。
- 使用B手机登陆账号A,点击开通超级会员,进入到升级页面,进行补齐差价开通。
- A手机进行支付,B手机进行支付。服务器认为你补齐了多个月份的超级会员,然后到账多次。
- 其实这个和签约漏洞的原理差不多,绕过了支付后服务器才去校验是否可以升级的逻辑。
订单关闭
- 使用优惠券创建一个订单,停留在支付界面
- 关闭订单,返回优惠券
- 使用优惠券再次创建订单;把第一个未支付的订单进行支付
- 商品从关闭,重新进入到了代发货的阶段,优惠券却仍然存在,即证明漏洞存在
支付金额
- 有些业务在支付时会忽略分以后的单位,这时候就导致了存在分单位的金额也可以生成订单
- 比如0.019=0.02,在支付时客户端给服务器传了0.019元的订单。而第三方付支通常最小的单位为分
- 这就导致了返回的金额会吧后面的9屏蔽掉,只返回0.01(也有些直接四舍五入变成0.02的)
- 当你支付完0.01后,第三方会通知服务器支付成功,而服务器那边生成的是0.019,可能这个软件的侨胞最小单位也是分,四舍五入变成了0.02
int整数溢出
注意:在做溢出测试时,有可能导致目标服务器宕机,需要向授权单位申请授权后才能进行测试。
- int的范围是-2147483648~2147483647。你可以把它看作是一个循环,当超过最大值后就重新从0开始计算
- 比如2147483649=-2147483647。有时候支付里面没有负数所以从0开始计算了
- 当支付金额为2147483649时,支付金额就变成了1,即2147483649-2147483648=1
- 支付的时候可以直接吧金额改成这个值,在测试商品时也可以让总价格为这个数。2147483648/物品单价+1=物品数量
- 以上的做法目的,简单的来说就是通过整数溢出来修改支付金额或者购买商品数量。
突破时间限制
一些网站中的限时活动设置了活动时间范围,可以通过抓包尝试更改时间参数为活动未限定范围内的。
前端验证
前端加密、后端解密校验。比如在用户登录时,通过抓包发现用户密码被加密传输了,可以利用一些解密工具进行破解,如:Burp解密或者一些在线解密网站。
暴力破解/撞库
首先在没有验证码或者验证码可以被绕过的情况下,尝试5次或者10次账号密码登陆,检测目标是否封禁账户,如果没有封禁规则,可以不断进行爆破。采用账号密码爆破,对于一些商城、应用、*、学校采用撞库方式判断是否存在该账号(需要准备各类字典:手机号撞库、邮箱撞库、姓名撞库)。
密码找回
- 通过邮箱找回密码,访问链接重置密码,输入新密码后提交抓包,虽然有token,但是依然可以直接修改用户ID进而修改他人密码
- 通过他人手机号找回密码,抓包,将他人手机号替换为自己的手机号,获取验证码,提交后修改密码
- 通过自己手机号找回密码,获取验证码后抓包,将数据包中的用户ID改为他人账号ID,提交后成功修改他人密码
- 通过邮箱找回密码,URL链接中修改用户ID为他人,邮箱不变,之后通过链接可以将他人账户绑定为自己的邮箱,之后通过邮箱找回密码
任意url跳转
url跳转漏洞也叫开发重定向漏洞,可以把用户重定向到攻击者自己构造的页面去,简单的说就是可以跳转到任意指定的url。一般出现在验证跳转、sso登陆等位置。
服务端未对传入的跳转url变量进行检查和控制,可能导致可恶意构造任意一个恶意地址,诱导用户跳转到恶意网站。
危害:
- 网站钓鱼
- 配合CSRF操作危险请求
- 配合XSS执行JS盗取cookie
- 配合浏览器漏洞(CVE-2018-8174)
http://www.xxx.com?url=https://www.baidu.com
替换url参数后能够跳转到对应页面,但是一些网站可能会对url跳转做限制,可以尝试绕过bypass
1.利用问号绕过限制,最终跳转到京东页面
url=https://www.baidu.com?www.jd.com
2.利用@绕过限制,最终跳转到京东页面
url=https://www.baidu.com@www.jd.com
3.利用斜杆反斜杠绕过限制
4.利用#绕过限制
url=https://www.baidu.com@www.jd.com
5.利用子域名绕过
6.利用畸形url绕过
7.利用跳转IP绕过
支付逻辑漏洞
在支付环节中由于逻辑不严谨而产生的漏洞称为支付漏洞。
测试思路
只要有参数,都可以修改,都有可能出现问题。
通常使用两个账号来对比测试,这样可以更快发现可疑参数
订单模块
- 下单之后修改商品价格
- 下单之后更改数量设为负数,产生正负逻辑
- 并发购买是否出现逻辑问题
- 商品为0,是否存在购买的可能
- 生成订单时修改订单金额
结算模块
- 优惠券重复利用
- 修改结算状态
- 更改支付API或者支付模式
- 伪造成功结算请求
退货模块
- 更改货物状态
- 更改退货价格
收货模块
- 绕过客户直接确认收货
边界值问题
正常的逻辑是用户购买商品,然后价格累加得到一个总价进行扣款。这个时候就会产生逻辑问题:如果说用户购买的商品是负数了,那么计算的总数就是负数。反过来钱给用户
顺序执行缺陷
正常的逻辑是a-b-c-d 循环渐进的进行流程操作。这个时候就会产生逻辑问题:可以直接从中绕过某一个过程进入到下一步操作。如果说有一项是支付的操作,那么也就会产生支付绕过,如果说有一项是验证机制,就会绕过验证直接进入下一步。
金额直接传输导致篡改
直接对下单的金额进行修改值,这里可以使用fd或者burp抓包
确定支付之后还可以加入购物车
把商品放入购物车点击下单支付,会跳转到微信,支付宝等第三方支付平台。这个时候还可以继续在购物车中加入商品,支付结束之后,商家发放的商品是现在的购物车里面的东西。
请求重放
购买成功之后,继续重放请求,可以让购买的商品一直增加。购买成功之后,会有一个银行对商户网站跳转的过程,如果反复进行操作,有几率会导致商品反复购买和增加,但是不需要付更多的钱。
请求参数干扰
金钱做了签名认证之后,修改后不通过,但是在里面仍然会有一个参数对金额产生影响导致问题产生。
订单替换
订单替换发生在支付之后的事件处理,同时向服务器发起二次支付请求一个多一个少,支付金额少的,然后支付之后进行替换,告知服务器订单支付完成,并且过程可以反复的回放。
欺诈
需要两个收款人,一个是正常的商家,一个是伪造的商家
单位替换
产生在paypal类似的国际支付的场景。
用户替换
在支付过程中发生用户替换现象,首先登陆自己的账户,然后取得另外一个人的账户名等有效信息,在业务流程中用对方的用户名替换自己的用户名,用对方的余额购买完成后,再替换自己的账户名,这样就形成别人的钱买自己的东西
强制攻击
强制攻击发生在暴力破解的情况下,如果一个商家运用一个自己的网店,接入第三方支付接口,由于设计上的不当导致商家与第三方支付约定的密钥Key可以单独被MD5加密,导致可以使用MD5碰撞技术对密钥进行破解,攻击者可以设计简单的密钥加密信息使得MD5加密是可以用MD5碰撞技术进行暴力破解。
秘钥泄漏
内置支付功能的app为了设计上的方便有可能会把Md5或者是RSA的私钥泄漏导致攻击者反编译apk之后获取密钥信息使得交易信息可以被篡改。
13.函数修改:apk反编译之后的函数修改,可能导致商家在最后一步向支付方提交订单时未验证信息的准确性,仍然被篡改。
修复建议
- 生成数据签名,对用户金额和订单签名
- 敏感参数不要放在url中
- 服务端校验/过滤客户端提交的参数
- 在服务端计算金额的时候,一定要判断是否为正数
- 支付过程中加一个服务器生成的key,用户校验参数有没有被篡改
- 用url传递相关参数,后端进行数字验证
- 订单金额和充值接口返回的数据进行校验
- 提交订单时后台判断单价是否与数据库中相符,若不符则返回数据
- 支付时应从服务器拉取数据,而不是直接读取客户端的值