depy

It is a long and beautiful life.

depyword-进阶开发记录

项目

前言

depyword是我自己独立开发的一个渗透测试报告生成系统,详情可见:点击我

之前考虑到一些因素,打算不插入详情,但感觉不插入详情这个系统真的米有意义,所以打算拓展它。

拓展功能

每一次开发前都需要去考虑,我的系统目前可以做什么,还有什么缺少的地方?根据缺少的功能我需要拓展出哪些东西以及需要什么知识储备?拓展开发后需要注意哪些特殊场景?

depyword的1.0雏形只可以通过表单提交后生成一个不含详情的基本模版。虽然在一定情况下可以减少时间,但是懒人的最高目标就是不需要二次打开,生成就是成品。所以,我需要对漏洞细节这个部分进行完善,但是这块非常困难。

为什么呢?就好比漏洞详情吧,你不可能没有图片,而你的图片不可能只有一张,而我的系统对于图片插入和文字插入是两种不同的模式。至少我现在也没有想到怎么插入html代码给word。所以我一直僵着不想动。

今天突然想到,如果纯粹的图文并茂不行,那我把文字和图片分开来不就行了。文字表示漏洞的介绍、触发点、poc。图片代表实际演示,咨询了一下之前的客户,对我这样的文档表示可以接受。

那么就简单了,首先我们需要一个文本域来接受详情,因为input框不能换行。

605dbf52394c8.png

提交之后发现他会把我们输入的换行变成\n。

但是插入到word里面并不会解释\n,所以需要一个替换去解决。

$detail = str_replace("\n","<w:br/>",$bugs[$i]['bugremark']);   //详情换行符替换

这样就可以把换行符变成word里的换行了,效果类似:

6055b461e480e.png

所以这里是可以解决的,最麻烦的还是图片。

首先是图片上传的问题,我真的很害怕被人上传shell。于是百度了一个非常粗暴的方式过滤

6055b4d06a0d7.png

也就是说我们的文件后缀、文件名并不来自于用户输入,而是通过$file_type,最终我们会把后缀控制在三个主流的图片后缀中。

这样的话通过前端调用图片上传,最终返回文件名,达成文件名无法控制(需要防范的就是解析漏洞了,所以日后再做对文件内容的校验了,不过目前nginx没爆啥bug,所以暂时不重要)

这个做完之后就是下一步了,例如我添加漏洞,设置相关图片,如果是多图的话肯定也是通过图片url然后分行获取。写三行代码就行了:

          $imagearr = explode(PHP_EOL, $bugs[$i]['bugimages']); //根据换行符分割图片
          $path = realpath(__DIR__."/image/");
          $path = $path."/".$imagearr[$j];

然后就是最难的地方了,动态插入图片。

我们的想法是,使用块复制,通过数组中图片的数量(这里有个小trick,即使图片为空默认会有一行记录)生成图片块,图片块使用6055b73416331.png

但是这里发现是二级复制,因为前面还有个块复制(根据漏洞数)所以先不着急渲染,看看进行漏洞数块复制后我们的win_block2会变成啥样。

测试完就能知道,它变成了 win_block2#1[第一个漏洞的图片块部分],而bug_image变成了 bug_image#1。

接着使用块复制来复制win_block2(复制三个),测试完发现变成了bug_image#1#1  bug_image#1#2这样类似的图片块。

总而言之,我们的思路是这样:

1.获取漏洞类型数(例如3个类型漏洞)

2.复制三个漏洞块

3.根据每个漏洞类型的补充图片数量分割后获取数组长度(判断数组第一个元素trim后是否为空,为空代表没有图片)

4.根据数组长度 复制 图片块

5.根据数组内容进行图片插入

大致代码如下:

        for($j=0;$j<$imagerows;$j++){
          setImageValue('bug_image#'.($i+1)."#".($j+1), ['path' => $path,'width'=>500,'height'=>500]);
        }

i代表第几个漏洞,j代表第几张图片。搞清楚这个逻辑,就变得简单了。

动手实践

6055b9ca15237.png

6055b9d11d338.png

605dbf8cda573.png

做完之后需要一直debug 控制变量测试 基本正常 项目完结 

3.21补充:

发现几个特殊场景,比如我们的详情需要插入我们的代码,而代码或多或少存在<>等符号,而这些符号会被word识别,然后报错导致word打不开。

6056dee823b74.png

所以需要解决我们输入代码的时候产生的问题,大致的思路如下:

  1. 用户输入内容后转义(使用htmlentities)

  2. 转义后再替换换行符(不然会把换行符的<也转义了)

  3. 插入详情

代码如下:

    $detail = htmlentities($bugs[$i]['bugremark']);
    $detail = str_replace("\n","<w:br/>",$detail);   //详情换行符替换
    $tmp->setValue('bug_detail#'.($i+1),$detail);   //设置细节

后记

虽然我很想用java写,但是php真的是世界上最好的语言诶。