SSRF入门详解

  • List item

SSRF学习:

SSRF概念:

SSRF全名:Server-Side Request Forgery:服务器端请求伪造
在一些网页上,存在服务端发送请求的状态,因为存在服务端发送请求,那么我们通过URL可以传入我们需要服务端解析的内容,比如测试内网端口是否开放,访问内网文件,这就是SSRF,当然,这只是最基础的内容

SSRF漏洞的主要函数:

file_get_contents:

使用条件需要将php.inl的allow_url_open设置为ON,否则不能使用
先看源码:


    <?php 
    if (isset($_POST['url']))  
    {  
    $content = file_get_contents($_POST['url']);  
    $filename ='./images/'.rand().';img1.jpg';  
    file_put_contents($filename, $content);  
    echo $_POST['url'];  
    $img = "<img src=\"".$filename."\"/>";  
    }  
    echo $img;  
    ?> 

解析一下:
isset:判断变量是否非空,非空则返回true ,是空则返回faluse
file_get_contents:把文件读入一个字符串或者把文件读入到另一个文件中去。
如上述代码第五行:是把$content的内容保存到filename中。
$img:一个文件名:图片形式,图片从url里面去获取

这段代码使用file_get_contents函数从用户指定的url获取图片。然后把它用一个随即文件名保存在硬盘上,并展示给用户。
利用:
1:利用这个函数去判断端口是否开放
2:如果开放,端口里面有内容的话,有可能就会返回该网页源码

fsockopen:

fsockopen : 打开一个网络连接或者一个Unix套接字连接
格式:fsockopen(主机名称 hostname,端口号 port,错误号的接受变量 errno,错误提示的接受变量errstr,超时时间 timeout)
port:端口号,如果对该参数传一个-1,则表示不使用端口,例如unix://。
errno:如果errno的返回值为0,而且这个函数的返回值为 FALSE ,那么这表明该错误发生在套接字连接(connect())调用之前,导致连接失败的原因最大的可能是初始化套接字的时候发生了错误。
errstr:错误信息将以字符串的信息返回。
timeout:设置连接的时限,单位为秒。
关于这个函数的理解(先看源码):


   <?php  
   function GetFile($host,$port,$link)  
   {  
   $fp = fsockopen($host, intval($port), $errno, $errstr, 30);  
   if (!$fp) {  
   echo "$errstr (error number $errno) \n";  
   } else {  
   $out = "GET $link HTTP/1.1\r\n";  
   $out .= "Host: $host\r\n";  
   $out .= "Connection: Close\r\n\r\n";  
   $out .= "\r\n";  
   fwrite($fp, $out);  
   $contents='';  
   while (!feof($fp)) {  
   $contents.= fgets($fp, 1024);  
   }  
   fclose($fp);  
   return $contents;  
   }  
   } 
   ?> 

理解一下上面的源代码:

$out = "GET $link HTTP/1.1\r\n";  
$out .= "Host: $host\r\n";  
$out .= "Connection: Close\r\n\r\n";  
$out .= "\r\n"; 

理解之前先来补充一下下面这些知识:(请求一个网页的时候需要这些头信息 没问题)
GET / HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Connection: Keep-Alive

第一行:说明了该请求是GET请求。该行的第二部分是一个斜杠(/),用来说明请求的是该域名的根目录。该行的最后一部分说明使用的是HTTP 1.1版本(另一个可选项是1.0)。那么请求发到哪里去呢?这就是第二行的内容。

第二行:是请求的第一个首部,HOST。首部HOST将指出请求的目的地。结合HOST和上一行中的斜杠(/),可以通知服务器请求的是 www.wrox.com/(HTTP 1.1才需要使用首部HOST,而原来的1.0版本则不需要使用)。

第三行中包含的是首部User-Agent,服务器端和客户端脚本都能够访问它,它是浏览器类型检测逻辑的重要基础。该信息由你使用的浏览器来定义(在本例中是Firefox 1.0.1),并且在每个请求中将自动发送。

第四行:是首部Connection,通常将浏览器操作设置为Keep-Alive(当然也可以设置为其他值)注意,在最后一个首部之后有一个空行。即使不存在请求主体,这个空行也是必需的。

了解了上面的知识后,我们再来看看fscokopen的请求信息:
$out = “GET $link HTTP/1.1\r\n”;
$out .= “Host: $host\r\n”;
$out .= “Connection: Close\r\n\r\n”;
$out .= “\r\n”;
\r\n 表示结束和换行
第一行就是一个请求信息
第二行就是一个访问网址
第三行必须了(现在我也不懂)
第四行可有可无就是表示一个结束换行
把这些请求信息写入到我们fsockopen中,就构成了一个HTTP访问信息
在这里插入图片描述同样的看这样的一个代码:要去读写一个文件
feof函数:如果出错或者文件指针到了文件末尾(eof)则返回 ture,否则返回 faluse。这样就保证了读取

fgets() 函数会在到达指定长度( length - 1 )、碰到换行符、读到文件末尾(EOF)时(以先到者为准,停止返回一个新行。如果失败该函数返回 FALSE。

同样,如何利用这个函数:只要能够通过服务器去访问一个端口或者链接,那么就可以去探测端口

格式:url=…&port=8080(要探测的端口)

cure_exec:

使用条件:PHP版本>5.3并且extension=php.curl.dll需要开启
使用dict协议探测端口: url=dict://地址+端口

其他信息:Banner

banner中可能包含的信息
软件开发商
软件名称
服务类型
版本号(可以通过版本号来发现已知的漏洞和弱点,这是最重要的)

利用CURL通过gopher协议发送请求:

瑞士军刀—nc:

nc的主要作用,目前我已经接触到的就是对端口起监听作用:
在这里插入图片描述表示我对自己主机的8080端口进行了监听,可以接受我们对端口发送的数据(nc功能强大,如有需要自己可以去看,这里贴上链接https://blog.csdn.net/zdzzdz123123/article/details/104136838?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-1&spm=1001.2101.3001.4242)

curl:

简单来说,个人感觉curl就是避免了我们需要的WWW去请求,而实自己可以编写请求的数据东西,通过自己定义的协议去请求。
检查一下CURL支持哪些信息:
在这里插入图片描述这里我的版本号是7.55.1,不支持gopher协议
7.55.0支持gopher协议

如何发送GET请求:

我们先随便抓个包来看看请求格式是什么样子的:
在这里插入图片描述在前面我们讲fscokopen的时候就讲过了http请求的格式,这里再次重述一下:
HTTP:GET/请求的网址 HTTP/1.1(1.1是版本号)
Host:请求网页的ip地址

固定的格式:curl gopher://请求地址的端口/HTTP+HOST(均用url编码包括换行符)
发送之后我们请求的所有信息都会出来
在这里插入图片描述
包括了页面返回信息
因为这里是GET请求,所以我们要请求的东西就都在URL里面了完结

如何发送POST请求:

GET请求只需要2个字段:头字段和Host
但是POST请求还需要另外两个字段:content-type和content-length
这里就需要我们自己去构造,当然,你想通过抓包截取也可以。
关于content-type:告诉客户端返回内容的类型,常见的content-type有四个取值,这里贴一下链接https://www.cnblogs.com/fighter007/p/10917026.html
感觉最常见的就是这个content-type:application/x-www-form-urlencoded 其他的如果遇到了就自己去查吧
content-length:content-length主要是告知服务器大小我传输的数据有多大,并且返回的时候返回的length也是那么大一般不可缺少。如果传入的内容和length不符合,那么要么服务器等待传入多的字节,然后服务器超时,要么就提前结束
刚刚看见一篇文章https://www.cnblogs.com/nxlhero/p/11670942.html里面说如果没有content-length的话:
在这里插入图片描述对此我们有了新的发现,可以等于content-length或者没有,那么我们通过transfer-encoding头也可以进行判断大小(把我们的数据以块的形式传输,当块为0的时候传输就结束了,大小也就计算出来了)这里贴几个链接方便下次阅读:
在这里插入图片描述
网址1

网址2

网址3
这个问题的讨论就有点复杂了,这里就不讨论了(太菜了,不知道咋弄了)
总而言之,发送POST请求和GET请求差不多,知识多了两行内容:content-type和content-length

关于SSRF基础的绕过:

1、攻击本地

http://127.0.0.1:80
http://localhost:22

2、利用[::]

利用[::]绕过localhost
http://[::]:80/ >>> http://127.0.0.1

也有看到利用http://0000::1:80/的,但是我测试未成功

3、利用@

http://example.com@127.0.0.1

4、利用短地址

http://dwz.cn/11SMa >>> http://127.0.0.1

5、利用特殊域名

利用的原理是DNS解析

http://127.0.0.1.xip.io/

6.利用句号

127。0。0。1 >>> 127.0.0.1
(做题的使用用过,好像没啥用)

7、利用进制转换

可以是十六进制,八进制等。
115.239.210.26 >>> 16373751032
首先把这四段数字给分别转成16进制,结果:73 ef d2 1a
然后把 73efd21a 这十六进制一起转换成8进制
记得访问的时候加0表示使用八进制(可以是一个0也可以是多个0 跟XSS中多加几个0来绕过过滤一样),十六进制加0x

http://127.0.0.1 >>> http://0177.0.0.1/
http://127.0.0.1 >>> http://2130706433/
http://192.168.0.1 >>> http://3232235521/
http://192.168.1.1 >>> http://3232235777/
http://0/

CTFSHOW里面的的题目:

没有过滤:

在这里插入图片描述
直接随便传就可以了

过滤了localhost、127.0.0.1、.、。:

在这里插入图片描述这里尝试用127。0。0。1,但是没啥用,于是就用了进制转换。
http://127.0.0.1 >>> http://2130706433/
在这里插入图片描述

对传入域名长度有限制:

在这里插入图片描述
http://[::]:80/=127.0.0.1
http://0’flag.php
即可

利用@

在这里插入图片描述根据正则表达式来看:用@即可

利用DNS解析定向到127.0.0.1

上题目:
在这里插入图片描述
全都ban完了,那就使用DNS重定向
可以在自己服务器或者某些网站上去搞一个域名ip地址指向127.0.0.1的域名,弄进去就可以了。
这里强调一下这个DNS重定向
上题:在这里插入图片描述题目要求我们的ip是54.87.54.87,但是我们要访问的话是通过127.0.0.1去访问,因此我们需要传入一个域名可以解析为54.87.54.87和127.0.0.1的域名,那么上网站,解读一下页面内容:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210209214524957.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MTM1MzAyOQ==,size_16,color_FFFFFF,t_70

此页面将帮助生成主机名,用于测试软件中的dns重新绑定漏洞。

要使用此页,请输入两个要在其中切换的ip地址。生成的主机名将随机解析为使用非常低的ttl指定的地址之一。

划重点,ip地址可以在域名中切换,且是随机的(有其他师傅给出了解释的,我就不说了因为我不懂)
这样下来,多打几次,就OK了

题外话:

redis相关的渗透和攻击 还没有学习,在大概学完了安全漏洞之后会再次去学习

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值