Yakit插件⼩案例⸺XSS盲打助手

作者:@奶权师傅

插件功能简单介绍

应key⼦哥要求,来分享点yakit的小小小姿势

⽤Yakit写mitm插件真的是比burp简单太太太多了,简化了很多繁琐的内容,⽐如画ui,可以真正做到让⽤户专注于插件的逻辑,⽽不是想着怎么画ui等⼀些与功能⽆关的东⻄。

⼀步⼀步来吧,⾸先我们创建⼀个新插件,依次点击插件商城->新插件

接着选择MITM模块

填好相关的表单后,点击创建新的Yak模块,因为我们这⾥是XSS盲打插件,需要⼀个盲打的 Payload,所以需要用户设置⼀个参数,可以在增加参数⾥⾯找到

点击完创建新的Yak模块后到插件商店⻚⾯就可以看到新加的这个插件了,点击修改插件,然后再 点击⼤屏模式就可以开始开始写插件相关的代码逻辑了

接下来就是本⽂的重点了。进入到内置的编辑器后可以看到作者给出了⼀个模板,其中yakit_output(MITM_PARAMS)代表打印插件参数,可以点右上角的调试按钮进行调试。

填好参数后点击提交

可以看到插件给我们输出了⼀个日志信息,也就是说我们可以通过 MITM_PARAMS[key] (这⾥的 key取决于外⾯设置参数时所填写的值)来获取参数内容(以当前插件来说就是获取XSS盲打⽤的Payload)

紧接着往下看,模板内定义了⼀个__test__函数,这个函数只会在调试的时候运⾏,也就是说这个插件在正式插⼊到MITM功能的时候是不会运⾏__test__函数的,那么我们就可以在这⾥⾯写测试⽤的逻辑

__test__ = func() {  
    results, err := yakit.GenerateYakitMITMHooksParams("GET", "Example Domain")  
    if err != nil {  
        return  
    }  
    isHttps, url, reqRaw, rspRaw, body = results  
  
    mirrorHTTPFlow(results...)  
    mirrorFilteredHTTPFlow(results...)  
    mirrorNewWebsite(results...)  
    mirrorNewWebsitePath(results...)  
    mirrorNewWebsitePathParams(results...)  
}  

__test__里面调用的mirror*函数(这里是模拟一下调用,在MITM中的话会自动hook到这些函数上)其实是一些钩子函数,分别对应了五种情况。具体会在什么时候被调用,作者的注释也写得非常完善。

# mirrorHTTPFlow 会镜像所有的流量到这里,包括 .js / .css / .jpg 这类一般会被劫持程序过滤的请求  
mirrorHTTPFlow = func(isHttps /*bool*/, url /*string*/, req /*[]byte*/, rsp /*[]byte*/, body /*[]byte*/) {  
      
}  
  
# mirrorFilteredHTTPFlow 劫持到的流量为 MITM 自动过滤出的可能和 "业务" 有关的流量,会自动过滤掉 js / css 等流量  
mirrorFilteredHTTPFlow = func(isHttps /*bool*/, url /*string*/, req /*[]byte*/, rsp /*[]byte*/, body /*[]byte*/) {  
      
}  
  
# mirrorNewWebsite 每新出现一个网站,这个网站的第一个请求,将会在这里被调用!  
mirrorNewWebsite = func(isHttps /*bool*/, url /*string*/, req /*[]byte*/, rsp /*[]byte*/, body /*[]byte*/) {  
      
}  
  
# mirrorNewWebsitePath 每新出现一个网站路径,关于这个网站路径的第一个请求,将会在这里被传入回调  
mirrorNewWebsitePath = func(isHttps /*bool*/, url /*string*/, req /*[]byte*/, rsp /*[]byte*/, body /*[]byte*/) {  
      
}  
  
# mirrorNewWebsitePathParams 每新出现一个网站路径且带有一些参数,参数通过常见位置和参数名去重,去重的第一个 HTTPFlow 在这里被调用  
mirrorNewWebsitePathParams = func(isHttps /*bool*/, url /*string*/, req /*[]byte*/, rsp /*[]byte*/, body /*[]byte*/) {  
      
}  

了解得差不多了我们就可以写这个XSS盲打小助手插件相关的代码了。

XSS盲打小助手

我们的只需要用到最后一个钩子,也就是每当出现一个新的参数的时候,就会调用这个函数。

mirrorNewWebsitePathParams = func(isHttps /*bool*/, url /*string*/, req /*[]byte*/, rsp /*[]byte*/, body /*[]byte*/) {  
      
}   

使用fuzz模块构造一个新请求

 freq, err := fuzz.HTTPRequest(req, fuzz.https(isHttps))  
die(err)  

接着遍历一下所有的参数

 for _, param := range freq.GetCommonParams() {  
    yakit_output(param.Name())  
}  

然后我们写好一个__test__函数

 __test__ = func() {  
    isHttps = false  
    // 构建一个测试请求  
    rspRaw, reqRaw, err := poc.HTTP(`  
POST /hello?test=a HTTP/1.1  
Host: 127.0.0.1:8080  
  
`, poc.https(isHttps))  
    die(err)  
  
    // 从响应报文里拿body  
    body, _ := str.ExtractBodyFromHTTPResponseRaw(rspRaw)  
    // 从请求报文里拿url  
    url, _ := str.ExtractURLFromHTTPRequestRaw(reqRaw, isHttps)  
  
    results = [isHttps, url, reqRaw, rspRaw, body]  
  
    mirrorHTTPFlow(results...)  
    mirrorFilteredHTTPFlow(results...)  
    mirrorNewWebsite(results...)  
    mirrorNewWebsitePath(results...)  
    mirrorNewWebsitePathParams(results...)  
} 

点击调试并输入插件参数后

可以看到我们的url参数被输出了,并且这个参数是有一个Fuzz方法的(Yak Fuzz库教程:https://www.yaklang.io/docs/buildinlibs/lib_fuzz),我们试着把插件参数放入到Fuzz方法中,并且再调用Show方法看一下。

for _, param := range freq.GetCommonParams() {  
    param.Fuzz(MITM_PARAMS["payload"]).Show()  
}  

在终端里面可以看到请求的原文,yak的Fuzz库已经帮我们构造好请求了,我们只需要发送出去即可

 for _, param := range freq.GetCommonParams() {  
    param.Fuzz(MITM_PARAMS["payload"]).Exec(httpool.https(isHttps))  
}  

然后我们就完成了一个最最最简单的插件的编写了,是的你没听错就是这么方便。当然你还可以再加一些细节,比如记录一下测试了多少个参数了。

testParamNum := 0  
# mirrorNewWebsitePathParams 每新出现一个网站路径且带有一些参数,参数通过常见位置和参数名去重,去重的第一个 HTTPFlow 在这里被调用  
mirrorNewWebsitePathParams = func(isHttps /*bool*/, url /*string*/, req /*[]byte*/, rsp /*[]byte*/, body /*[]byte*/) {  
    freq, err := fuzz.HTTPRequest(req, fuzz.https(isHttps))  
    die(err)  
  
    for _, param := range freq.GetCommonParams() {   
        testParamNum += 1  
        yakit_status("已测试参数数量", testParamNum)  
        param.Fuzz(MITM_PARAMS["payload"]).Exec(httpool.https(isHttps))  
    }  
}  

最后的效果:

并且,freq.GetCommonParams()还帮忙把POST请求时Content-Type为JSON的情况也考虑到了。

这意味着如果在MITM中遇到了JSON格式的POST正文,Yak也会解析其中的参数(目前只会解析一层的数据,但是作者说将来会更新到可以解析更深的嵌套json格式!!),这一点是在burp不容易做到的。只能说http://yaklang.io牛皮!

Yak官方资源

Yak 语言官方教程:
https://yaklang.com/docs/intro/
Yakit 视频教程:
https://space.bilibili.com/437503777
Github下载地址:
https://github.com/yaklang/yakit
Yakit官网下载地址:
https://yaklang.com/
Yakit安装文档:
https://yaklang.com/products/download_and_install
Yakit使用文档:
https://yaklang.com/products/intro/
常见问题速查:
https://yaklang.com/products/FAQ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值