たれながし.info

とあるITエンジニアの備忘録

ランサムウェアグループの投稿を収集するツール「ransomwatch」を動かしたい

ここ数年ランサムウェアの被害が継続発生しています。収まる様子は見られません。
ランサムウェアの攻撃グループは、攻撃の成功や身代金の要求を彼ら自身が運営するWebサイトに投稿することが多いです。ほとんどのサイトはTor経由でないとアクセスできない.onionドメインのサイトです。

そういったランサムウェアグループの投稿を自動収集するための「ransomwatch」というツールがあります。ソースコードGitHubで公開されています。

github.com

「ransomwatch」は、作者の人がツールを定期稼働させて、結果を「https://ransomwatch.telemetry.ltd」で公開しています。なので、本来は自前の環境で動かす必要はありませんが、動作の仕組みが知りたかったので、自前の環境で動かしてみました。
結論としては、うまく動かない部分があって途中で諦めました。しかし、ここに奮闘の結果をメモしておきます。

また「ransomwatch」からフォークした「ransomware.live」というツールもあります。
こちらもgithubでソースコードが公開されていて、実行結果が公開されているサイトがあります。
こちらの方が頻繁に更新され高機能なので、「ransomware.live」を使った方が良かったのかもしれません。

動作環境について

「Torプロキシ」と「ransomwatch」を動かす必要があります。
今回は、Windows上でDockerを稼働させ、Docker上で「Torプロキシ用のコンテナ」と「ransomwatchのコンテナ」を稼働させます。必ずしもDockerを使用する必要はないですが、Dockerを使うと楽です。


  • ホストOS:Windows11 22H2 Enterprise x64
  • Docker Desktop:4.25.0
  • Ubuntu on WSL2:22.04.2 LTS

環境構築

WSL2とDockerをインストールした後、コンテナを起動します。

WSL2のインストール

WSL2はDockerを動作させるために使用します。
MS公式の手順を元にインストールしました。
WSL のインストール | Microsoft Learn

PowerShellを管理者で起動し、wslをインストールする。

> wsl --install
…
要求された操作は正常に終了しました。変更を有効にするには、システムを再起動する必要があります。

Windowsを再起動する。WSL2上でUbuntuが起動するが使いません。

> wsl -l -v
  NAME      STATE           VERSION
* Ubuntu    Running         2

Docker Desktopのインストール

Docker DesktopをDLしてインストールする

> Start-BitsTransfer -Source "https://desktop.docker.com/win/main/amd64/Docker Desktop Installer.exe" -Destination "Docker 20Desktop 20Installer.exe"

「Use WSL 2 instead of Hyper-V」にチェックを入れてインストールする

インストールが完了したらWindowsを再起動

WSL2の状態を見ると、dockerが動作している

> wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu                 Running         2
  docker-desktop         Running         2
  docker-desktop-data    Running         2

Torプロキシ用のコンテナ起動

Torプロキシ用のコンテナを起動する

> docker run -p9050:9050 ghcr.io/joshhighet/torsocc:latest
Nov 03 15:17:14.214 [notice] Tor 0.4.7.13 running on Linux with Libevent 2.1.12-stable, OpenSSL 3.0.8, Zlib 1.2.13, Liblzma 5.2.9, Libzstd 1.5.2 and Unknown N/A as libc.
…
Nov 03 15:17:54.000 [notice] Bootstrapped 100% (done): Done

9050/TCPでTorプロキシが起動する

> docker container ls
CONTAINER ID   IMAGE                               COMMAND                   CREATED          STATUS          PORTS                    NAMES
364f5a623eb8   ghcr.io/joshhighet/torsocc:latest   "tor -f /etc/tor/tor…"   27 seconds ago   Up 26 seconds   0.0.0.0:9050->9050/tcp   kind_bohr

ransomwatchのコンテナイメージ作成と起動

ransomwatchをDLし解凍する

> Start-BitsTransfer -Source https://codeload.github.com/joshhighet/ransomwatch/zip/refs/heads/main -Destination ransomwatch.zip
> Expand-Archive .\ransomwatch.zip

dockerfileからイメージを作成する

> cd ransomwatch\ransomwatch-main
> docker build -t ransomwatch:1.0 .
[+] Building 357.5s (17/17) FINISHED

>docker image ls
REPOSITORY                   TAG       IMAGE ID       CREATED          SIZE
ransomwatch                  1.0       c818deea9ad0   14 seconds ago   2GB

コンテナを起動しbashで接続する

> docker run -it --name ransomwatch --entrypoint "/bin/bash" ransomwatch:1.0

vimのインストール

# apt-get install vim

ransomwatchが参照するプロキシのIPアドレスを修正する
127.0.0.1だとコンテナ内を参照してしまうので、ホストのIPアドレスを参照するように変更

# vim sharedutils.py21行目を書き換えます。
修正前)sockshost = '127.0.0.1'
修正後)sockshost = 'host.docker.internal'

「/source」ディレクトリを作成する

# mkdir /source

ransomwatchの利用

ransomwatchを使っていきます。

スクレイピングの実施(scrape)

「scrape」でランサムウェア攻撃グループのWebサイトをスクレイピングする。
スクレイピング結果はコンテナ内の「/source」にhtmlファイルとして保存される。

スクレイピングの実施

# python3 ransomwatch.py scrape

2023-11-03:17:59:44,273 INFO     sharedutils: attempting socket connection
2023-11-03:17:59:44,291 INFO     sharedutils: socket - successful connection
…
2023-11-03:18:35:00,161 INFO     ransomwatch: scraping http://threeamkelxicjsaf2czjyz2lc4q3ngqkxhhlexyfcp2o6raw4rphyad.onion successful
2023-11-03:18:35:00,162 INFO     ransomwatch: saving /source/threeam-threeamkelxicjsaf2czjyz2lc4q3ngqkxhhlexyfcp2o6raw4rphyad.html
…
2023-11-03:18:35:29,480 INFO     ransomwatch: scrape run complete

完了すると「/source」にhtmlファイルが作成される

# ls -l /source

-rw-r--r-- 1 root root    2305 Nov  5 01:41 0mega-omegalock5zxwbhswbisc42o2q2i54vdulyvtqqbudqousisjgc7j7yd.html
-rw-r--r-- 1 root root    1205 Nov  5 01:47 0xFFF-contiuevxdgdhn3zl2kubpajtfgqq4ssj2ipv6ujw7fwhggev3rk6hqd.html
-rw-r--r-- 1 root root   34094 Nov  5 01:28 RAMP-rampjcdlqvgkoz5oywutpo6ggl7g6tvddysustfl6qzhr5osr24xxqqd.html
-rw-r--r-- 1 root root   14373 Nov  5 01:47 abyss-3ev4metjirohtdpshsqlkrqcmxq6zu3d7obrdhglpy5jpbr7whmlfgqd.html
-rw-r--r-- 1 root root   49720 Nov  5 01:48 akira-akiral2iz6a7qgd3ayp3l6yub7xx2uep76idk3u2kollpj5z3z636bad.html
…

パースの実施(parse)

「parse」で取得したhtmlから投稿を抜き出す
パーサーがおかしいのか異常終了したため、ここで諦めました

# python3 ransomwatch.py parse2023-11-04:02:13:45,99 INFO     sharedutils: running shell command -
    grep --no-filename '<a href="/company/' source/cuba-*.html | cut -d '/' -f 3 | cut -d '"' -f 1 | sort --uniq | grep -v company

grep: source/cuba-*.html: No such file or directory
Traceback (most recent call last):
  File "//ransomwatch.py", line 242, in <module>
    parsers.cuba()
  File "/parsers.py", line 298, in cuba
    posts = runshellcmd(parser)
            ^^^^^^^^^^^^^^^^^^^
  File "/sharedutils.py", line 176, in runshellcmd
    cmdout = subprocess.run(
             ^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/subprocess.py", line 571, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '
    grep --no-filename '<a href="/company/' source/cuba-*.html | cut -d '/' -f 3 | cut -d '"' -f 1 | sort --uniq | grep -v company
    ' returned non-zero exit status 1.

Webページの生成(markdown

markdown」でパースした結果から、markdown形式のWebサイトを生成できるらしいです。
今回はパースができなかったので、試せていません。

# python3 ransomwatch.py markdown

結論

ということで、スクレイピングはできましたが、その後の処理が実施できませんでした。
「ransomwatch」を稼働させるだけでも、修正が必要な部分がいくつかあったので、大変でした。とはいえ、大体の仕組みは分かったので個人的には満足です。

自前でランサムウェアグループの投稿を収集したい人は、「ransomwatch」より「ransomware.live」を使った方がいいのかもしれません。もしくは自作のツールを作るとか…。
こんな記事もあります。

xtech.nikkei.com

個人的なメモ:コンテナの操作

私はDockerをほとんど触ったことがなかったので、今回知ったDocker操作コマンドのメモです。

・稼働中のコンテナ一覧の確認
> docker container ls

・停止中含めたコンテナ一覧の確認
> docker container ps -a

・ローカルのファイルをコンテナにコピーする
> docker cp [ローカルのファイルパス] [コンテナID]:[コンテナのファイルパス]