什么是redis
redis是一个key-value型的存储系统,value可以是字符串(string),哈希(map),列表(list),集合(sets)和有序集合(sorted sets)
基本操作:1
2
3
4
5redis-cli -h {{ip}} -a {{password}} -p {{port}} 连接redis
config set dir {{dir}} 设置目录
config set dbfilename {{filename}} 设置文件名
redis-server /etc/redis/redis.conf 启动redis
/etc/init.d/redis-server stop/restart/start 重启redis
redis未授权访问漏洞
漏洞原理
redis并不强制要求设置密码,没有设置密码的情况下可以空密码登录。登录之后,可以利用redis进行各种写文件操作,达到getshell的目的。
配置时踩到的一些坑
一开始在自己的VPS上搞的,后来不小心搞得ssh都登不上去了,决定还是用虚拟机吧。。配置的时候出现了挺多玄学问题,下面给出完整的配置:
首先,/etc/redis/redic.conf
改了两个地方,一个是端口,一个是绑定的IP。改端口是因为我用默认的6379一直不能成功写文件,绑IP为0.0.0.0是为了能远程访问。
然后,/etc/systemd/system/redis.service
添加一条ReadWriteDirectories
为-/var/lib/redis
(跟redis.conf
指定的工作目录保持一致)然后服务重启一下,应该就可以了,应该。
写webshell
redis可以直接在网站根目录写webshell,过程如下:解释一下,config set rdbcompression no
是设置redis不对内容进行压缩,以免当内容较长的时候被压缩,失去作用;flushall
是为了清空key,因为save的时候会把之前留下的key也一起save进去,有可能会造成影响。这时候,目标网站根目录的对应文件已经被修改成这样可以看到,key和value都会被写入,再到目标网站试试,是可以正常耍的~
写authorized_keys
通过往/root/.ssh/authorized_keys
里面写你自己的公钥,可以实现免密码登录。过程如下:可以看到,往目标服务器的/root/.ssh/authorized_keys
里写入了本机comrade用户的公钥,接下来只需要切换到comrade用户,然后直接ssh去登就可以了有时候,题目可能出于害怕,不给你root权限,直接就不设置root下的.ssh
目录。这时候往普通用户目录下写也是可以的~权限没那么高,但是读个flag还是没什么问题当然,这些的前提是目标服务器有ssh服务,而且如果是登录root用户,/etc/ssh/sshd_config
的PermitRootLogin
要设置成yes才ok。
写/etc/passwd实现任意账号密码重置
/etc/passwd
和/etc/shadow
是存放密码的文件,一般来说为了实现写入,我们写的都是/etc/passwd
,因为/etc/passwd
一般比较好读到,而/etc/shadow
,普通用户是没有读权限的,写/etc/passwd
利于备份和恢复,何况还有个优先级。先来说一下/etc/passwd
的格式,/etc/passwd
中的数据是这样的用:分隔开,分别是用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录Shell
,这里我们只关注前两个字段,用户名和口令。如果/etc/passwd
的口令字段是x,说明口令以/etc/shadow
中的为准。口令部分用$符号分为三个部分,依次是:算法代号、salt、哈希值。Linux规定算法代号1代表MD5,5->SHA-256,6->SHA-512。在无法查看/etc/shadow
的情况下,我们不知道采用的是什么算法,但是问题不大,一般来说MD5,SHA-256,SHA-512都是支持的。
如果一个账号同时在/etc/passwd
和/etc/shadow
中同时存放了密码,系统将会以/etc/passwd
中的为准,除非/etc/shadow
中相应用户的密码字段是!,表示强制采用/etc/shadow
中的密码,同时,由于在/etc/shadow
中,如果密码字段中存在不属于集合{./0-9a-zA-Z}
的字符,则对应的用户是不能登录的,后面我也会说这里要怎么处理。
我们可以用mkpasswd
命令来生成口令,如mkpasswd --method=md5 --salt='my0salt0' 'aAsc_2123ASS'
。
我们要做的就是,把我们自己生成的口令放到口令字段,去构造一个新的/etc/passwd
,从而实现任意账户密码登录。过程如下:
普通用户在/etc/passwd
中是这样存放的:severus:x:1000:1000:severus,,,:/home/severus:/bin/bash
可以看到,第五个字段是服务器的名称,但是前面也说了,第五个字段是注释性描述,即使不填东西也没关系,其他部分就一目了然了。首先我们生成一个口令,密码最好不要太简单,以免系统强制要求密码必须有一定强度。然后同样的用redis去写,注意要带上sshd。此时/etc/passwd
是这样的普通用户成功了,那么root行不行?当然是可以的,但是要稍微复杂一点,之前提到了,如果/etc/shadow
的口令字段是!,说明这个用户不能使用口令登录,所以这里要求目标服务器的这个地方不能是!,但是默认是!,所以要自己去改一改。然后同样的去构造root的payload,root在/etc/passwd
是这么存放的:root:x:0:0:root:/root:/bin/bash
,过程如下:尝试了一下,其实用任意用户名,然后把权限设成和root一样也是同样的效果:可以看到,fuck用户也是root权限。最后记得把/etc/passwd
复原。
带密码的redis
一些情况下,redis可能带密码,这时候可以用hydra去爆破。做个示例:
首先在靶机给redis设置个密码,/etc/redis/redis.conf
中:然后用hydra愉快地爆破