逻辑漏洞概要
逻辑漏洞就是基于开发人员设计程序的时候,逻辑不严密,导致攻击者可以修改、绕过或者中断整个程序,让程序按照开发人员的预料之外去执行。
比如某一网页的登录验证逻辑如下:
输入用户名验证--验证成功后输入密码--输入验证码--数据包前端传到后端处理--数据库匹配--匹配成功回包 由于整体网站可能采用前端验证,黑客可以直接篡改或者绕过某些流程,如下:
BP抓取用户名,密码、验证码特定格式--发送给后端匹配
由于网站采用前端验证,导致攻击者可以直接抓取数据包,从而绕过用户名验证的过程,直接爆破,简单来讲,只要你能修改、绕过、中断整个开发者运行软件的整体逻辑,这个便是逻辑漏洞,只是绝大部分逻辑漏洞的危害性并不高,比如:开发人员需要你先输入账号,在输入密码;但是你改变了这个逻辑,可以先输入密码,在输入账号,其实这个也是逻辑漏洞,只是这个漏洞没有任何危害;但是也有可能在某些特定情况下可以结合其他的漏洞可能产生新的风险
漏洞的根因
比如SQL注入:
程序的开发者也没有想过你可以拼接他的语言产生他预料之外的危害,他不过是按照程序逻辑完成了整个查询的动作 那么为什么会产生逻辑漏洞就很容易理解了:研发只负责满足客户的需求,大部分的研发并不懂安全,所以并不会带着黑客的思维考虑这个软件的安全
程序的本质就是按照研发设计的逻辑运行,这个过程中出现的所有漏洞,皆可以为逻辑漏洞
逻辑漏洞的分类
从漏洞的本质上,我习惯将逻辑漏洞分为两类:
- 软件(系统)设计之初便存在的漏洞
- 使用者未能安全使用软件所产生的
1、第一点很好理解,比如永恒之蓝,sql注入漏洞、文件上传等等,均为设计的时候未能按照安全设计的方法进行,所产生的,攻击者只需要找到特定的点,执行特性的代码即可产生研发预料之外的现象
2、第二点的关键在于使用者,比如弱口令,比如匿名用户;程序开发者会设计很多便捷的功能,但是由于使用者使用不当,产生了新的问题
但是我们本文章的目的,为web逻辑漏洞,去除常见的漏洞大类,比如:sql注入、文件上传等等;我们也将讲讲部分不好分类,但是在业务测对用户有影响的漏洞,就是下文中的漏洞
1.身份验证漏洞
爆破-验证码爆破实验(暴力破解漏洞)
渗透测试中最简单也最有效的攻击方式就是弱口令攻击,web 服务中最好用的爆破神器 就是 burpsuite 的 intruder 的模块,如果有验证码的话,如果验证码相对简单,就可以就用 pkav工具来试下,如果 bp 解决不了的话,就需要自己写脚本来爆破
以下,我们先来讲解一个pkav的爆破验证码的案列: 使用PKav HTTP Fuzzer 爆破带验证码的网站_pkav下载-CSDN博客
字典方面,可以参考自行到github上去收集常见的密码本,最好可以形成自己的密码库 当然,遇见复杂的但是又需要的爆破的需要自己根据实际的网站,进行脚本的编写,更好的达到爆破的目的:验证码识别可以参照 kuls大佬的文章:https://mp.weixin.qq.com/s/wUpKG7uifU_aj8oWYEPqqQ
实战中各种稀奇古怪的身份验证漏洞:
1.1 未限制爆破
未限制爆破,即对于用户登录的地方没有做什么限制爆破的策略,因此对于这个地方可以 直接使用 bp 来抓包放进 intruder 模块爆破, 参考dvwa low关卡或者pikachu《 基于表单的暴力破解》,不做详述
1.2限制IP爆破
某些具有安全意识的开发人员或运维人员,针对账户爆破问题就会使用限制攻击者 IP 的方式,当在短时间内有大量来自该 IP 的尝试登录 现象时就会封锁该 IP,导致该 IP 无法使用,针对这种情况,建议自己写脚本,调用 git 开源的代理 API 来爆破,当然也可以直接用别人的轮子
自建轮子的方法:首先需要新建一个代理池:现在好用的一般是收费版本,这里可以自行购买,我这里拿一个代理举例
然后使用python调用代理池进行爆破:
import requests
import re
def post():
curl = "https://ip.900cha.com/"
proxy = {'http':'47.92.113.71:80'} #代理地址以及端口,现在估计已经失效,如果需要使用,可以自建资源池
header = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3775.400 QQBrowser/10.6.4208.400'}
post = requests.get(curl,headers=header,proxies=proxy).text #请求报文
# post = post.encode('ISO-8859-1').decode("gb2312") #iso编码转汉字
# print(post) #打印网站
chuli(post)
#将丢给chuli进行取值
def chuli(post): #整体模块均为数据处理,取值
ip = re.findall('准确归属地:.*', post)[0] #取出IP地址
print(ip)
#输出地址
if __name__ == '__main__':
post()
1.3 限制密码错误次数来爆破
有些网站管理员会限制某个账号的登录次数,如果超过限制次数,账号就会被锁定, 除非管理员解锁或者设定一段时间过后自动解锁
由于他限制了一个账号,比如只允许输入5次,但是不限制你换个账号又可以输错5次,对于这种情况,通常可以采用弱密码反过来爆破账户的方式,即设置任意的不超过爆破次数的弱密码数量来反过来爆破用户名
如下图:通过12345678弱口令来爆破用户,可以比对长度后发现,test和admin账号存在,如果账号足够多,总会有弱口令的
1.4 暴力破解漏洞-多字段爆破
多字段爆破即需要爆破多个字段大于等于 2,比如说:需要同时爆破:账号密码验证码,当我们爆破一个网站时返回信息是用户名或密码 错误时,大多数时候仍然使用 burpsuite 的 Intruder 模块,只是与单个字段爆破选择的模式不同,但是当某几个字段相同的情况下,例如 在不仅在 post 内容中确定还要在cookie或者session或者token中确定的时候,也可以自己写脚本解决问题,如下如为pikachu token爆破的脚本
import requests
import re
purl = "http://192.168.1.157/pikachu/vul/burteforce/bf_token.php"
user_token = "27536628ca8f3b0818871451285"
proxy = {'http':'127.0.0.1:8080'}
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0',
'Cookie': 'PHPSESSID=17u0i2fakm84eq9oc24boc8715'}
def token(response):
user_token = re.findall('value=".*."', response)[0][7:-1] #取出token
return user_token
def uandp(user_token):
f = open('result.csv', 'w')
#把爆破结果储存到文件里,这里为csv格式
f.write('用户名' + ',' + '密码' + ',' + '包长度' + '\n') #给文件设置标题
sum = len(open("p.txt").readlines())*len(open("u.txt").readlines()) #密码本的总数量,最后得出进度
dan = 0
for u in open("u.txt") :
for p in open("p.txt") :
u = u.replace("\n","") #过滤掉回车符
p = p.replace("\n","")
session = requests.session()
#会话保持
data= {'username':u,'password':p,'token':user_token,'submit':'Login'} #初始数据
response = session.post(purl,data=data,headers=header).text
user_token = token(response)
result = u + ',' + p + ',' + str(len(response))
#用户名密码以及响应包长度
f.write(result + '\n') #输出到文件
dan = dan + 1
print("进度:"+str(dan)+'/'+str(sum)) #输出到终端
# print(response)
f.close()
if __name__ == '__main__':
uandp(user_token)
1.5 限制登录频率爆破
限制登录频率爆破即限制在一定的时间内爆破的次数,比如10分钟内只允许爆破10次,对于这种方式可以采用延时爆破的方式,但是可能 需要时间比较久,但总比手工爆破舒服,在bp上如下文设置,该时间以 ms 为单位(1000ms=1S)
1.6 Authorization 爆破
Authorization 爆破,狭义上单纯指 basic base64 爆破,比如tomcat的密码在传输的时候,是采用base64编码的,而广义上可以泛指经过 编码过后的用户名与密码
下面我们以 tomcat 的 basic 爆破举例:环境可以采用vulhub的tomcat8环境
cd vulhub-master/tomcat/tomcat8
docker-compose up -d
#路径
#后台路径如下:
http://192.168.10.223:8080/host-manager/html
#开启环境
使用bp抓包,结果如下
改代码经过base64解密后如下:
可以采用两种方法进行解码:
1、上文中的python直接编写代码
2、bp自带的base64也可以实现
1、首先讲抓到的报文丢给intruder,然后把下文所示变成变量
2、然后选择自定义迭代器,导入账号,密码,我这里测试,所以随便输入了密码
3、输入第二个字符英文冒号:
3、输入密码
4、添加规则
5、然后点击爆破就ok
1.7 密文传输爆破
渗透测试中,有时会遇到密码从客户端到服务端中间通过前端 js 代码将密码加密后,在发送给服务器,所以这个时候,我们可以采用bp 上自带的加密方法进行加密
常见的加密手法有MD5或者RSA,如果需要JS的复杂加密,也可以读懂JS的加密逻辑自定义Python进行爆破,或者使用python的 pyexecjs包来帮助你执行JS文件复现加密方法
1.8 未授权漏洞(cookie和session)
Session固定攻击(未授权)
漏洞介绍:会话固定攻击是利用服务器的session不变机制,借他人之手获得认证和授权,然后冒充他人 漏洞原理:在请求登录过程时 候,URL带有一个session,登录成功之后会将登录成功的信息绑定到这个session中,攻击者可以发送带有session的URL给相关工作人员诱 导其登录,相当于获取了其身份信息 漏洞点:在GET方法请求登录时候带有session值 修复思路:
只要避免在URL中带入session信息即可比较有效的防御
另外也要注意POST请求中带有sessionid进行session固定攻击,虽然可利用性比较低,但是建议修复
如下,测试方法可以直接赋值session 然后更换浏览器打开或者使用无痕模式打开即可,如果直接访问,不需要登录,说明存在该漏洞
Cookie欺骗漏洞
漏洞介绍:
通过伪造cookie信息能够伪造其他用户进行登录。
漏洞原理:
开发者为了方便将身份信息/登录信息明文或者只是简单编码、哈希之后存放在cookies中,网站通过获取得到的cookies进行 授权或者身份验证
漏洞点:
cookie中有明显或者只是简单编码、哈希的字段时候 修改lsLogin值为1可以判定为用户已经登录
漏洞修复 :
Cookie不应该存储可理解的身份信息和登录信息 按照规定,cookie对身份信息和登录信息的存储只能通过存储足够长度的随 机字符串进行,避免篡改
如果某网站的cookie:asp163=admin,那我们只需要等待管理员登录成功后,网站存在登录信息后即可进行登录,构造报文进行登录, 安装editthiscookie可以迅速看到cookie值如下
cookie 设计存在缺陷
Cookie 的效验值过于简单。有些web 对于cookie的生成过于单一或者简单,导致黑客可以对cookie 的效验值进行一个枚举,如下图所示
这家网站对于cookie的较验只单纯的采用了一组数字,并且数值为常量,不会改变,这样非常容易遭到黑客的枚举。
甚至有一些网站做的更简单,直接以用户名,邮箱号或者用户ID 等来作为cookie的判断标准。
cookie 设置存在被盗风险
有一些厂商为了图方便,没有对用户的cookie 做太多的加密工作,仅仅是单纯的做一个静态加密就完事了。
比如有个厂家web设置的cookie,解出来后是用户名。因此只要知道一个人的用户名就可以伪造对方的 cookie,登陆他人账户。
1.9未进行登陆凭证验证
有些业务的接口,因为缺少了对用户的登陆凭证的较验或者是验证存在缺陷,导致黑客可以未经授权访问这些敏感信息甚至是越权操作。
后台页面访问
某电商后台主页面,直接在管理员web 路径后面输入main.php 之类的即可进入。
某航天公司订单 ID枚举
仔细看,就可以找到规律,他就是固定0031003+数字+003+数字+003+数字,其实需要穷举的就是13位左右,如果能够访问,会泄露大量的用户个人资料