如何在Brupsuite中将一个GET数据包修改为POST数据包
[2021-05-05 11:38:39 更正了一处错误说法]
写在前面
在做一道CTF题是涉及到了文件上传,然后突然发现页面没有上传文件的按钮。
就像这样可以浏览本地并选定本地文件再点击上传的按钮竟然没有。
正文
先看一下正常上传POST变量和文件的数据包。
上传POST变量
输入123并上传,通过Brupsuite中可以看到:
这是作为表单的格式上传的POST变量,但POST变量可以用一种更加简洁的格式上传,我们用GET数据包修改那当然是修改起来越简单越好,而且这两种格式在结果上并没有差别(说法错误),所以这里只将说明如何修改成更简单的后者来上传。
#更正:实际上Content-Type的值application/x-www-form-urlencoded和multipart/form-data在结果是也是有区别的,前者告知了服务器提交的参数使用了url编码,故服务器对其解析时会使用URL来解码。具体效果如下:
[2021-05-27 08:55:08 突然发现在这里进行更正的时候使用了另外一个PHP文件,但没有说明。简单说这个PHP文件如图所示,先输出了一句"---the $_POST---"和换行,接着用了print_r输出POST数组中的键值]
关于POST共有四种常用提交数据方式,具体参考如下博客(博主不懂其他两个Orz):四种常见的 POST 提交数据方式(application/x-www-form-urlencoded,multipart/form-data,application/json,text/xml)_stay hungry ! stay foolish!-CSDN博客
BrupSuite提供了在这两种格式间转换的一键式操作,只需要在BrupSuite的请求消息框(注意保证在框中右键点击)中右键选择"Body类编码改变即可",如果携带的数据是文件时选择这种转换将按照文件中的name为变量名而文件内容为变量值的规则获得一个POST变量,这就会导致文件的filename在这一转换中丢失,但如果是POST变量则不用担心。
下面来说如何将一个GET数据包修改成如上图的携带POST变量的POST数据包,首先访问目标PHP文件(可以在上传的页面的源码中寻找<form>标签中的action属性来确定),然后用BrupSuite把数据包拦下来。
进行如下操作就可以修改成一个携带POST变量的POST数据包:
- 请求方式修改为POST
- 消息头中加上Content-Type:application/x-www-form-urlencoded
- 在消息主体中加上需要上传的POST数据
注:Content-Length并不是必须的
上传文件
先观察正常上传文件的数据包:
与上传一个POST变量的区别在于,与文件相关的部分存放在消息主体并且被一层字符首尾包裹,这串字符在消息头中的Content-Type中的boundary被规定,这个boundary起着一个分隔符的作用,此处先单独讲一下关于boundary的规则(根据服务器软件种类不同这个规则可能会有细微区别)。
boundary的值在Content-Type中是可以被自由规定的(甚至可以为空,但必须要保证在Content-Type中存在boundary=这串字符),独占一行的--加上boundary组成一个非尾部的分割符,后面接着的是与文件相关的部分,在其末端的下一行则又是--加上boundary组成的分隔符,但需要注意的是如果这行分隔符是尾部(后面没有其他文件数据)则应该在这行分割符的后面再加上--(即--加上boundart加上--)并换行。
关于文件数据主要有三部分组成:
文件信息中,filename为必要的,其余的form-data、name和Content-Type的值为不必要的(删掉后两者仅会导致目标PHP$_FILES数组中对应文件的对应数据为空,如果目标PHP存在文件校正则应补上,至于前者...好像没影响?)。此外空行是必要的,文件数据可以为空但必须独占一行。
下面来说如何将一个GET数据包修改成如上图可以上传文件,同样先直接访问目标PHP文件。
接着向请求包中做出如下更改:
- 请求方式修改为POST方式
- 消息头中加上Content-Type:multipart/form-data;boundary=XXX (XXX是你中意的字符,可以为空)
- 在消息主体中加上一个由boundary和--构成的分隔符(非尾部)
- 在填入分隔符的下一行填入Content-Disposition:(form-data;) (name="thefile";) filename="test.txt" (在一点中()包裹的为可选内容)
- (可选)在Content-Disposition下一行填入Content-Type:XXX (XXX为文件类型)
- 在上述内容的下一行填入文件数据 (不可见字符请以手动逐个字节添加,直接复制黏贴或导入文件会出现多余字符)
- 视情况在文件数据下一行添加boundary和--构成的分隔符(非尾部)或boundary和--构成的分隔符(尾部,在非尾部的部分再加上--并换行,表示此前的文件数据是最后一份)
- (可选)如果是多个文件请按照第4点往下执行
最后说一句
关于消息头Content-Length这个参数可以不用加上,因为Brupsuite在发包时会自动加上(用wireshark查看就能确认这一点)。此外传入GET值,POST值,和FILE文件这三者并不互相干扰,完全可以三个愿望一次满足(不是
文章难免有不足,欢迎各位师傅斧正。