^

记一次SSRF漏洞挖掘

入口点发现

找到一处接口,结构如下

https://***.***.***/***?src=内网图片地址&type=jpg&access_key=preview_test&src_sig=一串hash&expire=0

各参数组成

1.src 文件地址

2.type 文件类型

3.access_key 请求密钥(这里默认)

4.src_sig 文件签名

5.expire 有效期(这里默认为0 永久有效)

通过参数fuzz可知,文件签名与其他四要素有关。如果没有五要素匹配,则无法访问文件。

分析

文件签名长40位,推测是sha1加密。且与四要素有关联性,故无需碰撞。

所以任务是,推测出src_sig的生成方法。

本来一开始,只有4个要素的时候,我可以自动排列组合拼接。测试了几十次,却没有一次成功。怀疑缺少其他默认数据或者是加了畸形变化,当然也有可能是加了盐。

如果sig加了盐或者做了奇怪的变化算法不是简单的拼接(比如把某项值md5一下再拼接),那基本就不用破解了。如果没有,我们需要找一下是否还有其他的默认元素。

对于一个文件的默认元素,并且还方便提取的估计只有文件md5了。下载文件到本地,做一次md5。


拿到hash之后,我们的排列组合的元素达到了5个。这时,组合的成本实在太高了。毕竟有120种组合方式,得一直弄好几个小时。

脚本编写

现在我们需要对五个元素排列组合:

1.0

2.access_key

3.jpg

4.文件地址

5.文件md5

使用到python3中的itertools库和hashlib库。

设置target为我们的目标src_sig,代码大致如下

import itertools
import hashlib

strs = [] #需要排列组合的元素列表
target = "" #目标sha1

count = 0
for i in itertools.permutations(strs,len(strs)): #根据元素列表个数做排列组合生成,并遍历元素
    count= count+1   data = ''
    for j in range(0,len(strs)): #拼接元素
        data = i[j]+data
    a = (hashlib.sha1(data.encode("utf-8")).hexdigest()) #做sha1加密
    print(a)
    if(a == target):
        print('签名验证成功!') #签名匹配
        print(i) #生成这个元素的排列方式
    print()
print(str(count))

非常幸运的是破解成功了


可以看到是一个ak排列第一,时间戳排最后的拼接生成sha1方式。

于是我们就可以伪造地址和sig来做内网ssrf请求了。