- 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
网址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相关的渗透和攻击 还没有学习,在大概学完了安全漏洞之后会再次去学习