在web渗透测试当中,文件包含漏洞,SSRF,XXE等漏洞都会涉及到伪协议的利用,接下来是我整理的一下常用的伪协议的利用,若有不足欢迎补充。
不同的开发语言支持的伪协议不同,在这里为主要讲一下常用的file、ftp、http、dict、gpoher以及部分PHP常用的伪协议
在接下来的文章当中,主要使用PHP语言为例,不同语言文件包含的函数或者ssrf使用的函数略有不同,但是在黑盒测试当中区别不大。
文件包含漏洞与SSRF
在具体讲解伪协议之前,先讲一讲文件包含漏洞与SSRF的基本原理。
文件包含
文件包含简单而言就是程序员在编写代码的时候为了方便将重复使用的函数封装到一个代码文件当中,在编写代码时,需要调用该文件内部函数时,通过直接包含对应对应的文件即可,无需重复书写方法。文件包含漏洞可能出现在任何一个开发语言当中,文件包含漏洞在PHP Web Application中居多,而在JSP、ASP、http://ASP.NET程序中却非常少,甚至没有,这是有些语言设计的弊端。
并且无论包含什么类型的文件,都会被当作脚本语言去执行,如果无法执行就会直接输出在页面。
常见的函数
参考:文件包含漏洞原理分析 - 知乎 (zhihu.com)
SSRF
SSRF是一种攻击方式,攻击者诱导服务器发起HTTP请求去访问任意URL,包括内部网络和本地文件。服务器请求的结果可能不会直接显示在前端,是否显示取决于具体的代码逻辑。本质是通过服务器去访问一个url,可能存在有回显和无回显的情况。
在PHP当中,ssrf是通过curl_exec()或者file_get_contents()函数实现的,但是前者不支持php://伪协议。
常见的通用伪协议:
file
file 本地文件传输协议
file:///path
file伪协议简单而言就是一个文件读取协议。这个文件常用于读取目标文件内容。
在上面的示例当中使用file读取ygg.txt文件的内容。
经过测试,在文件包含漏洞当中使用file问协议,可以使被包含的文件当中脚本被执行。
SSRF当中,使用伪协议包含数据如果是php代码可能不会直接输出到前端
显示文件被读取内容后直接被输出。
http
http 超文本传输协议,通过此协议可以访问一个http网页。
在使用http伪协议时需要注意的时,文件路径是基于WWW目录开始查出,并且范围限制在web目录。
在文件包含漏洞当中,通过http去访问一个文件,首先也是将文件包含执行,再根据代码是否回显,与访问的服务器无关。
目标文件代码是本地服务器执行。
SSRF当中,使用http协议是去访问目标服务器,显示的内容与服务器相关。
目标文件代码是被访问的服务执行。
dict
dict://协议只适用于SSRF,并且在php当中只有curl_exec()函数可以执行dict伪协议。
dict是网络字典协议,网上的资料很少,简单而言就是在服务器上定义关键字,通过dict://关键字,就会返回信息。在ssrf当中,通常用来端口探测,指定对应的端口也会返回模糊的端口信息。
返回当前中间件为Apache OPENSSL等信息,可以内网端口的存活情况。
返回数据库版本信息。
gopher
gopher伪协议是十分重要的一个协议,在ssrf当中可以利用gopher伪协议攻击内网的redis,FTP等,gopher可以看作是http协议的前身,支持TCP数据流的传输。
gopher://<host>:<port>/<gopher-path>_<TCP数据流>
<port>默认为70
发起多条请求每条要用回车换行去隔开使用%0d%0a隔开,如果多个参数,参数之间的&也需要进行URL编码
goupher伪协议关键点在于tcp/ip数据流的构造
推荐使用项目,Gopherus 通过脚本一件生成目标tcp/ip流
PHP伪协议:
PHP 伪协议的出现是为了提供一个 统一的
、简洁的
接口来处理 不同的数据流
。这些伪协议可以被看作是一种 桥梁
,它们允许开发者 使用常规的文件操作函数来处理各种不同的数据流
。
php://input
通过php://input可以基于POST请求上传可执行的php代码。 这个伪协议使用时会受到限制enctype=”multipart/form-data” 的时候 php://input 是无效的
如果权限足够可以使用这个伪协议实现木马的写入。
php://filter
官方的解释是:php://filter
是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。
使用格式
名称 描述
resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流。
read=<读链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
write=<写链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
<;两个链的筛选列表> 任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。
经常使用的就是read 读取目标数据,并且使用base64加密后输出。
php://filter/read=convert.base64-encode/resource=upload.php
data
与php://input类似,只不过是通过GET传递参数
http://127.0.0.1/include.php?file=data://text/plain,<?php%20phpinfo();?>
data://text/plain,
data://text/plain;base64,