CTFSHOW-SSRF

文章发布时间:

最后更新时间:

  1. SSRF开始啦

    题面如图,经典开场

    image-20220910120744221

先来看看curl_setopt里面的选项设置

1
2
CURLOPT_HEADER						启用时会将头文件的信息作为数据流输出。
CURLOPT_RETURNTRANSFER true 将curl_exec()获取的信息以字符串返回,而不是直接输出。

​ 当前目录存在flag.php(不过为啥扫不出来呜呜呜),但是需要以本地用户身份去访问

image-20220910141631405

自然就是利用SSRF伪造服务器身份去本地访问他就行,协议就是最常见的http

1
url=http://localhost/flag.php
  1. ssrf开始啦 限制内网IP

    题面如图,flag依然在于flag.php中,并且题目限制了url必须为http或http,以及黑名单过滤localhost/127.0.0.1

    image-20220910142215676

    看下parse_url怎么弄的

    image-20220910142639372

这里用到了之前的一个知识点,更改IP地址写法

http://www.jsons.cn/ipnum/ 或者转换成其他进制也可以

1
url=http://2130706433/flag.php
  1. ssrf开始啦 限制内网IP

    题面如图,flag依然在于flag.php中

    image-20220910143138686

截取的更短了,上面的可以继续打

或者题目环境为linux,所以0.0.0.0等价于127.0.0.1

image-20220910143403933

1
url=http://0.0.0.0/flag.php
  1. ssrf开始啦 限制内网IP 禁止30x跳转

    题面如图,flag依然在于flag.php中

image-20220910143811876

也就是直接过滤了0和1,不过过滤句号是什么鬼…

这里利用了DNS重绑定或者302跳转

https://blog.gm7.org/%E4%B8%AA%E4%BA%BA%E7%9F%A5%E8%AF%86%E5%BA%93/01.%E6%B8%97%E9%80%8F%E6%B5%8B%E8%AF%95/02.WEB%E6%BC%8F%E6%B4%9E/12.SSRF/01.DNS%E9%87%8D%E7%BB%91%E5%AE%9A.html

https://blog.gm7.org/%E4%B8%AA%E4%BA%BA%E7%9F%A5%E8%AF%86%E5%BA%93/01.%E6%B8%97%E9%80%8F%E6%B5%8B%E8%AF%95/02.WEB%E6%BC%8F%E6%B4%9E/12.SSRF/SSRF.html#%E7%9F%AD%E5%9C%B0%E5%9D%80--302%E8%B7%B3%E8%BD%AC-%E7%BB%95%E8%BF%87

对于DNS重绑定,这里不太好弄因为没域名。不过wp上他们找到了一个存在的值为127.0.0.1的A记录

http://sudo.cc/。我这里就用302跳转的办法,先向我的ip发起请求,然后跳转回flag文件处

image-20220910150752256

然后访问

1
url=http://43.140.198.45:81

尴尬了,应该是url_parse解析的缘故,那就用上面的吧

  1. ssrf开始啦 限制内网IP

    image-20220910163128708

这回是限制域名部分的长度,不过之前的过滤倒是没啦

用之前0.0.0.0的整数表示,即0即可直接访问

这里穿插一个本机ip/127.0.0.1/0.0.0.0的区别

https://www.cnblogs.com/HuiShouGuoQu/p/13445881.html

而且127.0.0.1是可以缩写成127.1

image-20220910165330719

所以即可用

1
2
3
url=http://127.1/flag.php
或者
url=http://0/flag.php
  1. ssrf开始啦 限制内网IP

    限制域名长度到3

    image-20220910165533193

    1
    url=http://0/flag.php
  2. ssrf开始啦 限制内网IP

    image-20220910170056762

1
2
3
4
5
6
7
8
9
10
11
12
gethostbyname()		成功时返回 IPv4 地址,失败时原封不动返回 hostname 字符串。
filter_var() 返回过滤后的数据,如果过滤失败则返回 false
查看其中的选定过滤器
FILTER_VALIDATE_INT
Validates value as integer, optionally from the specified range, and converts to int on success.String values are trimmed using trim() before comparison.

FILTER_FLAG_NO_PRIV_RANGE
Fails validation for the following private IPv4 ranges: 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16. 要求值不是 RFC 指定的私域 IP

FILTER_FLAG_NO_RES_RANGE
Fails validation for the following reserved IPv4 ranges: 0.0.0.0/8, 169.254.0.0/16, 127.0.0.0/8 and 240.0.0.0/4. 要求值不在保留的 IP 范围内
我们使用前面的那一套环路地址应该是触发了127.0.0.0/8这个限制

淦,涉及啦一些网段的知识还没搞懂

绕过用的就是之前的302条转或DNS重绑定,后者本质其实就是域名所有者可以随时修改解析的IP,对于浏览器来说,两次访问的都是同一域名,是符合浏览器的同源策略的,但是第二次访问解析到其他IP,调用到了其他资源。感觉还有点条件竞争,就是第一次解析的ip绕过if限制,然后之后再去访问的时候就解析到了其他ip上。直接上线上网站

在最后添加解析IP指向环路地址和设置一个任意地址

image-20220910172218728

多POST的几次,可以看到前面输出的是8.8.8.8绕过if,但是后面其实访问了127.0.0.1

image-20220910173812376

  1. ssrf开始啦 限制内网IP

    image-20220910174159454

这回换了个思路,也就是必须得是http://ctf.xxxxshow的才可以去访问

这里可以利用解析URL所出现的问题,也就是问题点出在parse_url()

https://www.cnblogs.com/tr1ple/p/11137159.html 给出了一些总结

自己也实践一下寻找一下这个函数的匹配规律

从解释上就已经可以看到,这个函数相对来讲是不安全的

image-20220911152919392

先给出一个较为完整、正常的解析

image-20220911153115379

从这里可以得出结论://后会解析到host;/后会解析到path

image-20220911153357321

特别地,如果//先跟到是?那么就会优先被解析到query,而不是path

还有一个特殊的@,会解析最后一个@跟到字符串作为host

image-20220911153951473

所以对于这道题,我们的目的是解析到hostlocalhostpath/flag.php

题目的限制为http://ctf.xxxshow

所以首先通过@来替换掉host,让前面的ctf.xxx变成user;对于后面结尾的show,可以通过放在query处

image-20220911154542502

1
url=http://ctf.xxx@localhost/flag.php?show
  1. 打无密码的mysql gopher协议

    题目给出了提示:无密码的mysql是什么意思? ssrf在什么地方呢

    先来分析一下题目,前端源码上看到了输入框的传递url,提交的数据会被发送至check.php。然后这里有个隐藏参数returl,修改一下参数值看看有无回显

    image-20220911155335451

    存在回显,证实了确实有ssrf在参数点returl上

image-20220911155707008

关于mysql与ssrf

https://paper.seebug.org/510/

gopher协议基本格式,主要都是基于tcp协议

1
gopher://<host>:<port>/<gopher-path>_后接TCP数据流

这个工具已经帮我们整理好了格式https://github.com/tarunkant/Gopherus

用python2写的,mac上不知道为啥pip不见了

直接用工具生成写一句话木马的payload

image-20220911164336348

image-20220911164904049

这里需要注意的是还需要将payload进行二次编码,因为在传输到服务器后会进行一次解码,会导致转义

image-20220911165147977

然后蚁剑连上就行

  1. 打redis

    题目直接给出了源码

    image-20220911170248972

ssrf参数点url,攻击内网redis

image-20220911170610197

直接打就行,后面依然连蚁剑