请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,猫哥的秋刀鱼回忆录及文章作者不为此承担任何责任。由于种种原因,猫哥的秋刀鱼回忆录公众号往后均不发表原创文章,欲转载随附出处即可且无需告会,文章质量且面向受众均偏向小白。本文内容部分案例转载选自农夫安全开源计划教材,本人对此进行二次叙述重新组织语言并附上新的案例,支持开源一波。
为什么说前言没有逻辑,因为它更像是在自我叨叨叨,众所周知我们现如今web应用程序都是通过逻辑来实现各种各样的功能。每一个阶段都会去执行一些数目庞大的逻辑操作。而这些逻辑后面却代表着一个复杂的受攻击面。举个例子,比如说警察逮捕犯人时,会根据犯人类型的不同去执行不同的执法手段,比如贩毒的最大的特征和签名是什么?是不是有两类:第一种只卖不吸毒的眼线极多眼光极高处处藏匿乖张,第二种又卖又吸的,性格反复无常且毒瘾发作明显的外貌并且区别大。这种逻辑算是对事物的一种签名式认知。比如SQL注入漏洞,它具有及其容易辨别的特征和签名,我们通常就是利用识别常见的恶意字符和语句去对他提前感知,提前截断预防。逻辑漏洞存在的面太广了,以至于它存在着相当多且复杂的受攻击面,从数据流转模块到认证模块再到业务流程模块,现如今都对它们的利用进行了广泛的研究。以至于在现在常见命题漏洞基本在大厂/高防护下遁形,SRC江山逻辑漏洞登顶皇位。但是我们会发现:
每一个逻辑程序的逻辑缺陷难以识别:因为每一种缺陷似乎是唯一的
为什么会这样理解,举个例子,你今天被仙人跳了,似乎是你中了皮条客的攻击,实际上是唯一的你受到了攻击,秉性乖张但全世界唯一的你,中招了!是不是上面的话这样说:每一个人的人性难以识别:因为每一个人是唯一的。你就能理解我的意思了,逻辑在SRC挖掘更多偏向与运气,你我虽然挖不到,但是我们今天好像只是在阐述一种命题的论证。一个程序开发者通常认为:如果出现A,那一定就会有B,因此我要执行C。但是实际上,攻击者会制造出X。所以逻辑漏洞也可以理解为用户的输入&行为不受控制并且不按套路出牌。
毫无疑问,羊毛出在羊身上,这种漏洞多半就在东哥的场子上,还有一些别的购物商城/在线支付平台(点卡充值等等),菠菜资金盘等等。常见的涉及到的有订单ID的篡改,商品编号的篡改,用户ID的篡改,金额的篡改,商品数量的篡改,积分以及代金券篡改。提一嘴,我们的工具就是Burp/yakit,不断地进行抓包改包测试,提交后看服务器的响应来进行挖掘的,接下来我们拿示例说话。
如下例子,我们在购买商品时进行抓包测试,先可以走一个正常的流程,看看请求/响应的数据包,是否存在验证等等,并尽可能发散思维的对数据进行篡改测试即可。
会抓取到一串bill1=4999&bill2=8999&num1=1&num2=0&uid=1
这样的信息,我们就可以分析是否在其中存在订单号的ID呢?比如说我买了iphone的订单号是20221920,买了mac的订单号ID的20221921,我们是否可以订单ID做一个篡改?让高价商品的ID流向低价商品形成差价购买?
比如在积分商城中我们利用低积分兑换高积分礼物,选取低积分礼物进行兑换,提交抓包修改其中的商品编号为高积分的商品编号提交,是不是也能测试是否存在逻辑上的漏洞呢?
比如有两个用户,admin用户ID为001,user用户ID为002,其他有1000个用户003-xxxx,如果我们在购买时修改了用户ID,是不是也可以触发?有人会问,订单的收货地址不对怎么办啊,呢如果我们把数据包发到intruder模块里,这个数据包就我自己在修改自己收货地址时抓的包,然后把用户ID为003-xxxx的用户信息中的收货地址全部改成我的收货地址手机号,是不是很恐怖?这个实际是水平越权漏洞的体现。
对于金额的测试,实际上我们通常都是取负或者乘0.01来操作,直接修改金额会触发某些逻辑,比如去和商品的金额进行对比然后拦截不正当的请求数据,或者我们可以把金额修改成算术题去绕或自身的逻辑都是可以的。比如我们抓包修改商品数量等字段,修改成任意数量(如负数)进行提交,查看能否以修改后的数量完成业务流程,很多商品限制用户购买数量,服务器仅在页面通过 JS
脚本限制,未在服务端校验用户提交的数量,通过抓包修改商品最大限制数量,即将请求中的商品数量改为大于最大数值限制,查看是否能完成修改后的数量完成业务流程。看几个例子:
在某网站提供在线购买礼品卡的功能。
抓包后把数值payprice(支付价格)修改为0.01,得到的内容大致如下:
且后续的测试中,礼品卡可用。
在某运营商的网盘的购买业务中,可抓取到的数据包如下:
disktype:购买的网盘类型
period:购买网盘按照年的方式购买
period_num:购买的年限
那么将period_num(购买的年限)的数值从1修改为-2后,生成的订单总金额为负数。
而当购买成功后,会发现钱包中的余额增加6000元。这是由于网站的计算逻辑为余额=钱包金额-(单价*数量)
而当单价或数量任一为负数时,则数学的逻辑则变成负负得正,从而导致钱包金额的增加。
在网站的支付功能模块中,优惠相关同样也可以构成逻辑的攻击面。说到优惠券就不得不吐槽下现在的电商。
以前想买个东西,领个优惠券,买得起我买,买不起我滚。
可现在哪是买东西啊,分明就是复习高等数学......
下面的案例是价格整合计算的时候逻辑所产生的问题。商城中存在的商品A如下:
商城中存在的商品B如下:
抓包,并将数量amount改为-1。
而由于有个负数的存在,导致订单信息产生了尴尬。所需要支付的价格为两个商品的差。
这些主要体现在:暴力破解,Cookie仿冒欺骗,Session欺骗延迟,前端js代码验证,服务器响应欺骗。这几个部分上,给大家举几个例子来更好的体会逻辑。
在没有验证码限制或者一次验证码可以使用多次使用的情况下,使用已知用户名对密码进行暴力破解,或使用一个弱口令密码对用户进行暴力破解。现在的组合拳都是社工库密码字典生成+暴力破解,比如最近泄露的推特数据,拿来直接做成字典,我有理由相信里面大部分国人的注册方式都是QQ邮箱对吧,然后根据泄露的个人信息,比如你的密码,生日,兴趣爱好,拿来生成一个字典,来爆破你其他门户的账号,是不是想想贼恐怖?不要被开户了但是思路就是这样。
假设现在有一个CMS
我们通过查看她的源码得知,后台地址/admin,登陆后的地址是/admin/index.php,当然我们直接访问,他就会根据控制checklogin.php对我们进行逻辑判断,这段代码就是说如果我们没有user的cookie值进行未授权访问,他就会给你跳转到login这个页面,仔细看实际上她的cookie是没有经过严格判断的,如果我们随便赋值一个cookie给user,是不是就可以绕过逻辑验证进行登陆?
直接未授权访问/admin/index.php被跳转
我们抓包看看,然后写cookie里写入; user=123
然后放包看看
成功的利用设计缺陷:cookie仿冒从而未授权进入后台页面,之后的每一次都会在cookie中去验证你是否拥有user这个值。
代码验证设计缺陷导致一些网站会利用 Cookie 是否为空、Session是否为 true 来判断用户是否可以登录,只要构造一个 Cookie或 Session为 true就可以绕过认证登录
比如说有这样一个站:http://192.168.10.159:8076/admin.php,我们在访问它的时候他就会用前端JS代码验证你是否合法登陆,比如一些未授权页面访问时,访问后弹框显示需要登录一般为JS代码验证,这种验证首先可以禁用本地JS代码功能来访问页面或者用burp抓包,骚一点就用拦截访问验证包来丢弃实现。
访问后台发现http://192.168.10.159:8076/admin.php被跳转至http://192.168.10.159:8076/admin.php/Login/index
抓
放
放
放(注意观察功能页面)
丢:到这里/admin.php/Login/index直接清空数据或丢包防止JS验证
点击添加管理员
继续清空然后添加新的管理员信息
添加成功就可以用新的信息去登陆
通过抓取某请求包,拦截对应响应包来修改服务器的响应。主要这个看看前端是否有控制页面走向的代码,比如说登陆成功服务器反馈 200 true 01 yes
等等信息,失败反馈302 false 00 no
,我们就可在提交请求时截取响应包并且修改服务器信息来达到登陆的目的,这个主要在资金盘等用TP开发的框架比较多见,由于没找到合适例子,不做具体演示。
常见的密码找回方式:
密码找回逻辑测试流程:
对于用户凭证我们可以尝试社工+爆破进行处理,还可以在指定别人用户密码找回时在接收验证码的时候抓包,把发送验证码的邮箱或者手机号改成自己的。指定自己密码找回最后提交的时候抓包把用户名或者用户ID改成别人的。或者修改提交的响应包来欺骗服务器验证。还有注册重复的用户名,例如 admin
,相当于修改了密码。还有关于通过密保问题找回密码,我们查看源码,密保问题和答案就在源码中显示,重置密码链接可以直接使用用户名来区别,改变用户名即可更改他人密码。在重新绑定时,给已知账户绑定手机,发现绑定手机的 URL
链接中有 uid
参数,修改 uid
参数为他人的,即可实现将他人的账户绑定上自己的手机,之后通过手机来修改密码修改个人资料处抓包,修改 userId
为他人,修改 mobilePhone
为自己的手机,即可实现将他人的账户绑定上自己的手机,之后通过手机来修改密码。通过邮箱找回密码,URL
链接中修改 用户ID
为他人,邮箱不变,之后通过链接可以将他人账户绑定为自己的邮箱,之后通过邮箱找回密码。还有跳过找回步骤:在正常流程下,密码找回,查看最后设置新密码页面的 URL
,记录下来继续返回密码找回处,输入其他用户名,提交找回申请,直接访问上面记录下的修改密码页面,成功修改密码。也可以正常流程下,修改密码页面抓包,修改其中的 USERNAME_COOKIE
为其他用户(有可能会经过编码,比如 base64
),提交即可修改其他用户密码,如果抓包其中有 step
参数,可以修改这个参数为最后一步(比如:5),提交便可略过之前的步骤。
在某次的安全测试中,我们遇到了一个非常典型的任意密码重置类漏洞。在网站的忘记密码
处的截图如下:
那么从图中能分析出来网站的工作过程如下:
1.通过手机号接受短信验证码
2.用户输入验证码
3.验证码与服务器的数值一致后,可以修改密码
而底层的判断逻辑为:用户提供了只有他才知道信息,从而判断为本人。随后按照正常用户的流程接收短信验证码,并填写正确的验证码。此时可抓取到的数据包如下:
而下一个步骤在网站的正常逻辑中,为修改用户的密码。
输入要修改的密码后,进行抓包
将userid字段替换为要修改的手机号,即可无感知的修改对方口令。
上面的案例,是通过修改发送包,而下面的案例来自于过去线下班学生的实践,是一个典型的通过修改返回包的逻辑漏洞。使用网站的正确流程修改帐号 A 的密码,抓包保存正确的返回包。
可以看到当密码修改成功后,返回包的内容为code:100000
等内容。而当我们想修改账户B的密码,由于没有正确的验证码,从而导致修改失败的返回包如下:
使用burpsuite,将正确的返回包,替换错误的返回包后,即可修改账户B的口令并成功登录。
在实际的漏洞挖掘中,类似的场景会出现变形,例如在登录界面,随意输入用户密码后,将false修改为true,亦或者status=0修改为status=1.
在一些逻辑漏洞的场景中,很多时候我们连抓包改包都不需要,正所谓生活不缺少美,只是缺少发现美的眼睛。某些网站会出现将短信验证码放置于返回包中。
我知道你现在莫名其妙的想笑,但这真的还不是低级错误的天花板。甚至于在实际的操作中,只需要将手机号输入到页面上,返回包中会出现用户的全部注册信息,这会包括手机号、姓名、邮箱、身份证号等等。
漏洞一般出现在数据交互的地方,用户可操作的地方,参数可控制的地方,比如说有个论坛我创建了一个aaa的用户,我在修改我自己密码的时候抓包,然后修改成用户admin,是不是可以把管理员的密码给改掉?这就是纵向越权危害极大,如果还有一个平行账号为bbb,如果我可以修改bbb的账号就是平行越权。我们可以控制请求参数,就可以控制我们的身份都算是越权漏洞。
该测试主要判断应用程序是否对业务预期范围外的业务请求做出正确响应。
乱序测试主要是对业务流程是否正常,确保攻击者无法通过技术手断绕过某些重要流程步骤,检验办理业务过程中是否有可控制来保证其遵循正常流程。正常流程如:
但是如果在第三步抓包分析,将注册的邮箱或者手机号改成别人的提交,看是否把账号注册成了别人的信息呢。如果成功则跳过了正常的业务流程,则存在该漏洞。同样的漏洞可能其他流程环节进行测试,如:支付,购物,注册,找回密码等过程检测。
逻辑漏洞与过往的漏洞对比后,我们会发现在逻辑漏洞中并没有清晰且明确的指纹信息。而例如SQL注入漏洞,我们可以通过请求包中的union、select等特定的内容字符进行识别。亦或者当命令注入漏洞,数据包中的whoami
以及返回包中的root
关键字,同样可以进行识别。一次成功的逻辑漏洞攻击尝试,往往数据包与服务器所要求一致且合法。所以在逻辑漏洞挖掘中,无法通过工具进行自动化的检测,而站在防守端,同样无法基于特征判断。那么挖掘逻辑漏洞最好的工具显然是Burpsuite,而实际的操作中,可以采用大致如下的方案:
尽最大可能的发散思维,不要限制住自己的思维,毕竟骚气才是逻辑漏洞最大的特色。我们写在这里,还是觉得安全更纯粹一点,至于如何论述脱了裤子放屁也是错?我只能说如果你脱了裤子在公共场合放屁,我觉的你是可爱,如果你在私密处偷偷脱了裤子放屁,我觉得我应该管不了这么多吧,但是现如今脱裤子并非多此一举,相反,它可以有效引起其他人注意,让你的屁更具有吸引力。但是我们论述的这个问题,很明显多此一举。