web-dev-qa-db-ja.com

wgetの小さなバージョン(51バイト?)

DVRの侵害に関するこのISCの記事 で、作者は組み込みシステムの侵害について話しています。特に、攻撃者はリモートホストで一連のechoコマンドを実行します。

このDVRには「アップロード」機能がありません。wgetも、ftpまたはtelnetクライアントもありません。

...

最初のエコーは51バイトを「/ var/run/Rand0-btcminer-arm」に書き込み、2番目のエコーは「done」を返し、システムが次のエコーコマンドの準備ができていることを示します。

名前が意味するのとは異なり、「Rand0-btcminer-arm」はビットコインマイナーではありません。代わりに、「wget」のバージョンのように見えます。

Wgetの基本的な基礎でさえ、どのように51バイトに収まるかわかりません。記事にはパケットダンプが含まれているので、ファイルに書き込んでバイナリをリバースエンジニアリングすることはできると思いますが、他にも何か問題があると思います。

これがどのように起こっているかを理解するのを手伝ってくれる人はいますか? 「バイナリ」はネットワーク機能へのライブラリ呼び出しを行っていますか?

28
lorenzog

著者は曖昧であるという間違いを犯し、読者を少し混乱させました。 PCAPダンプを見るまで、私は最初は混乱していたことを認めなければなりません。

まず第一に、ボックスには実際にwgetがありません

enter image description here

攻撃者はその1つのエコーステートメントを使用せず、一連のエコーステートメントを使用しました。私は約数えました107エコーステートメント実行可能ファイルを徐々に構築していますRand0-btcminer-arm。それぞれ約50バイトで、つまり約5350バイトです。単純なHTTPダウンロードを実現するのに十分以上の方法。

以下はそれらのスニペットです(赤で強調表示)。

enter image description here

33
Adi

私はdvrを危険にさらすコードを書いた人です。上記のように、バイナリを接続してファイルに「エコー」し、実行できるスクリプトがあります。生のバイトだけをファイルにエコーし、新しい行(-n)も除外しているため、結果は同じファイルになります。攻撃スクリプトで使用される関数を使用して、エコーラインのセットを自分で生成できます。

#get a list of echo commands we need to run
#by iterating through a file and converting sections of bytes (50 a time)
#into hex and then putting them into an echo -ne 'HEX' line
#additionally, we write \\x64\\x6f\\x6e\\x65 (ascii: done) which will allow us to verify that worked after
def getEchoList(localName, outputName, location):
    with open(localName, "rb") as f:
        converted = None
        result = []
        byte = f.read(1)
        i = 0
        current = ""

        while byte != "":
            if i == 51:
                i = 0
                result.append("echo -ne '%s' >> %s/%s && echo -e '\\x64\\x6f\\x6e\\x65'" % (current, location, outputName))
                current = ""
            current = current + "\\x"+byte.encode("hex")
            byte = f.read(1)
            i = i + 1

        if len(current) > 0:
            i = 0
            result.append("echo -ne '%s' >> %s/%s && echo -e '\\x64\\x6f\\x6e\\x65'" % (current, location, outputName))
            current = ""
        return result

list = getEchoList("some-binary", "to-echo-to", "/var/run")
for line in list:
    print(line)

明らかにこのコードは恐ろしいですが、私たちが使用していたものです。 open( '/ dev/tcp/IP/port')を実行できない理由は、dvrがbashを実行しないためです。これはbashに組み込まれていると思います。 DVRには最小限のbusybox環境があり、wgetやftpgetなど、実際にファイルを取得する方法はありません。完全なコードは http://Pastebin.com/s41eE1nM で入手可能

19
Retsam Tob

私は投稿の著者であり、確かに「1」は正しいです。 「wget」アップロードを構成するすべてのパケットを見つける最も簡単な方法は、wiresharkフィルター「tcp.stream eq 1」です(pcapについては、元の記事のリンクを参照してください)。

「TCPストリーム」に従って、142.0.45.42から192.168.1.100までの部分をフィルターします。

「名前を付けて保存」(未加工)すると、コンテンツを含むテキストファイルが作成されます。

お気に入りのテキストエディターでファイルを編集し、一連の「エコー」につながる行と、コマンドを実行する最後の2行を削除します。

「/ var/run」を「/ tmp」に置き換えます

(使い捨ての)Linuxシステムでスクリプトを実行します...バイナリになってしまいます

$ md5 Rand0-btcminer-arm
MD5 (Rand0-btcminer-arm) = d1232ef223445276fe5f0f854358f021
$ file Rand0-btcminer-arm
Rand0-btcminer-arm: ELF 32-bit LSB executable, ARM, version 1, dynamically linked (uses shared libs), stripped

「wget」と呼ぶ理由は、Wgetユーザーエージェントを使用しているためです。

$ strings Rand0-btcminer-arm  |grep Wget
User-Agent: Wget
5
dr. j.

この記事の例は、ファイルを段階的に構築するために使用される多くのエコーステートメントの1つにすぎません。 >>リダイレクション演算子。ファイルの既存のコンテンツを上書きせず、代わりに追加します。

記事からの引用:

攻撃者は、一連の「エコー」コマンドを使用して初期バイナリをアップロードするラッパースクリプトを使用しているようです。

4
bonsaiviking