一.起
是最近在实战中遇到的一个webvpn系统,有不少高校在使用,但是登录进来后发现几乎没有公开任何内网资产,都是国内外的期刊或者公共图书馆资源,于是想着能不能通过webvpn排查出更多内网中的资产面,于是便有了这篇文章。
二.承
以前遇到的一些vpn系统,在前台就有快速跳转的功能
点击访问后,url地址传给服务器,由服务器端进行加密,随后使用302重定向到加密后的地址:
如果我们要通过webvpn对目标内网中的http服务进行爆破的话,就可以通过,写脚本,调用上面的加密接口,获得响应包中的Location字段来获得加密地址,判断该地址能否成功访问的方式进行爆破。
但是这次遇到的webvpn系统却没有提供前台输入url地址直接跳转的功能,只能访问导航中给出的一些等公共资源
而且点击跳转后有没有看到服务器加密解密的过程,估计是在前端完成的url加密
还是先看一下网站结构,发现引用了aes-js.js文件,盲猜使用了aes加密。
由于该系统没有使用webpack打包,js也没有进行混淆或加密,所以给我们的调试工作带来了不少方便。
一般正常情况下遇到混淆的js代码,我都会先用工具搜索一下字符串,如果运气好可能一些密钥key就直接硬编码在了js里
但是这次没这么容易扫到什么敏感信息,那还是直接上F12大法吧
搜索encrypt字样,定位到portal.js文件,可以确认系统的加密是使用的aes-js库,而且定义AES加密模式是cfb
但是没有发现关键的key和iv,那就先找找key
原来是通过api获取的
通过burp抓包也得以验证,现在获取到了key和iv,我们再来认真分析下加密算法具体是如何实现的
text是待加密的明文参数,由于aes加密中要求明文的字节长度是16位的倍数,所以先使用textRightAppend()方法判断text字节长度,决定需不需要追加0来填充,然后将明文、key和iv使用toBytes()方法转换成utf-8编码的byte数组,new了一个aesCfb对象,使用上述的key和iv进行cfb模式的aes加密,由于没有声明填充模式,我们猜测是使用的默认的PKCS5Padding,又因为给定的密钥是16位,所以数据块应是128,最后将加密密文先转成十六进制字符串再slice一下,即只截取明文字符串两倍长度的密文字符串,和转成十六进制的iv拼接好,就形成了最终的密文。
知道了加密算法,我们再搜索encrypt字样看看哪里调用了加密算法
通过函数名encryptUrl可以大概猜到是对url进行加密的函数
结合console调试的结果,大概可以得知这样一个加密过程:首先生成协议名-端口,如果是https则不需要加上端口号,再得到encrypt()方法加密的主机地址,最后保留原有的url路径和query参数。
我们继续搜索encryptUrl字样找到调用了该方法的go函数
不难看出这个函数主要是用于实现跳转的,对于传入的url地址,分别用parseProtocol和parseHost方法分离出没有冒号双斜杠的协议名和主机地址,如果主机地址parse为空或失败的话,跳转到百度搜索,如果是http、https、ssh这些协议的话会先记录到历史,然后再跳转。
三.转
大概逻辑理清楚了,我们先验证一下:
将“www.baidu.com”进行aes加密后得到“e7e056d2253161546b468aa395364056”,截取长度26,即“e7e056d2253161546b468aa395”
将iv string转hex后的结果“77726476706E69737468656265737421”
两者拼接 = “77726476706E69737468656265737421e7e056d2253161546b468aa395”
和控制台调试的结果一致,验证成功,证明我们的分析没有问题。
四.合
最后要做的就是写个脚本进行爆破了
五.后话
后来对api进行深一步测试的时候发现,其实该系统还是配置了快速跳转的功能的,不过管理员默认关闭了,我们只需要修改一下响应包就可以成功使用这个功能,点击跳转后本质上还是调用之前分析的go()方法。
其实类似爆破还可以写油猴脚本,直接调用go()方法,会省下很多代码,但是脚本的优势也是很明显的,我们可以使用多线程,根据timeout和Location字段等方式判断目标是否可达。