🐻云函数攻防

Serverless概述

无服务器(Serverless)不是表示没有服务器,而是表示当您在使用Serverless时,您无需关心底层的资源,也无需登录服务器和优化服务器,只需关注最核心的代码片段,即可跳过复杂的、繁琐的基本工作。

Serverless 拥有近乎无限的扩容能力,空闲时,不运行任何资源。代码运行无状态,可以轻易实现快速迭代、极速部署。

什么是云函数

函数即服务提供了一种直接在云上运行无状态的、短暂的、由事件触发的代码的能力。

函数即服务和传统应用架构不同,函数服务提供的是事件触发式的运行方式,云函数不是始终运行的状态,而是在事件发生时由事件触发运行,并且在一次运行的过程中处理这一次事件。因此在云函数的代码中,仅需考虑针对一个事件的处理流程,而针对大量事件的高并发处理,由平台实现云函数的多实例并发来支持。

云函数(Serverless Cloud Function,SCF)是为企业和开发者们提供的无服务器执行环境,帮助您在无需购买和管理服务器的情况下运行代码。您只需使用平台支持的语言编写核心代码并设置代码运行的条件。

云函数无法长驻,调用的时候创建,执行完之后立即就销毁,所以无法直接保存状态。

云函数功能特性:

  • 代码管理

  • 支持多开发环境

  • 自动伸缩

  • 事件触发

  • 监控和日志

以函数为扩展单位,虚拟化运行时环境(Runtime),是现有计算资源的最小单位,具有完全自动、一键部署、高度可扩展等

使用云函数时,您只需使用平台支持的语言(Python、Node.js、PHP、Golang、Java 及 Custom Runtime)编写代码。而云平台将完全管理底层计算资源,包括服务器 CPU、内存、网络和其他配置/资源维护、代码部署、弹性伸缩、负载均衡、安全升级、资源运行情况监控等。

Serverless 帮助用户脱离繁冗的开发配置工作,只需关注业务代码逻辑的编写,不用任何的基础设施建设、管理与运维开销。该服务模式降低了研发门槛,提升业务构建效率,获得了大量企业和开发者的支持。

  • 多种部署方式,适应各种环境

  • 多样化触发,支持更多业务场景

  • 自动化弹性执行,贴合调用曲线

  • 按需付费,毫秒级计费模式

云函数(Serverless Cloud Function,SCF)提供代码部署、镜像部署两种部署方式,支持事件函数和 Web 函数两种函数类型。

SCF 事件函数有三个基本概念:执行方法、函数入参和函数返回。

执行方法

执行方法:对应项目的主函数,是程序执行的起点。

在调用云函数时,首先会寻找执行方法作为入口,执行用户的代码。用户需以文件名.执行方法名的形式进行设置。

用户设置的执行方法为 index.handler,则 SCF 平台会首先寻找代码程序包中的 index 文件,并找到该文件中的 handler 方法开始执行。

函数入参

函数入参,是指函数在被触发调用时所传递给函数的内容。

通常情况下,函数入参包括 event 和 context 两部分,但根据开发语言和环境的不同,入参个数可能有所不同

· event入参

event 参数类型为 dict,event 中包含了触发函数执行的基本信息,可以是平台定义的格式,也可以自定义格式。函数被触发开始执行后,可以在代码内部对 event 进行处理。

有两种方法可以触发云函数 SCF 执行:

1. 通过调用 云 API 触发函数执行。

2. 通过绑定 触发器 触发函数执行。

· context入参

context 为 SCF 平台提供的入参,将 context 入参传递给执行方法,代码可通过解析 context 入参对象,获取到运行环境及当前请求的相关信息。

函数返回

SCF 平台会获取到云函数执行完成后的返回值,并根据下表中不同的触发方式进行处理。

同步触发

Ø 通过 API 网关、云 API 同步 invoke 触发函数的方式为同步触发。

Ø 使用同步方式触发的函数在执行期间,SCF 平台不会返回触发结果。

Ø 在函数执行完成后,SCF 平台会将函数返回值封装为 JSON 格式并返回给调用方。

Ø 异步触发

Ø 使用异步方式触发的云函数,SCF 平台接收触发事件后,会返回触发请求 ID 。

Ø 在函数执行完成后,函数的返回值会封装为 JSON 格式并存储在日志中。

Ø 用户可在函数执行完成后,通过返回的请求 ID 查询日志获取该异步触发函数的返回值。

触发器和触发源

  • 任何可以产生事件,触发云函数执行的均可以被称为触发器或触发源。触发器在本身产生事件后,通过将事件传递给云函数来触发函数运行。

  • 触发器在触发函数时,可以根据自身特点,使用同步或异步方式触发函数。同步方式触发函数时,触发器将等待函数执行完成并获取到函数执行结果;异步方式触发函数时,触发器将仅触发函数而忽略函数执行结果。

  • 腾讯云云函数在和腾讯云的某些产品或服务对接时,也有自身实现的一些特殊方式,例如推(PUSH)模式和拉(PULL)模式。

    • 推模式:触发器主动将事件推送至云函数平台并触发函数运行。

    • 拉模式:云函数平台通过拉取模块,从触发器中拉取到事件并触发云函数运行。

触发事件

触发器在触发函数时会将事件传递给云函数。事件在传递时以一个特定的数据结构体现,数据结构格式在传递时均为 JSON 格式,并以函数 event 入参的方式传递给云函数。

触发事件的 JSON 数据内容,在不同的语言环境下将会转换为各自语言的数据结构或对象,无需在代码中自行进行从 JSON 结构到数据结构的转换。 例如,在 Python 环境中,JSON 数据内容会转变为一个复杂 dict 对象,即函数的入参 event 就是一个 Python 的复杂 dict 对象。而在 Golang 或 Java 中,入参是一个需要和 event 数据结构可以匹配的对象。

Serverless 扫描技术

云函数端口扫描

# -*- coding: utf8 -*-
from socket import *
 
def main_handler(event, context):
IP=event["queryString"]["ip"]
port=event["queryString"]["port"]
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 port
except Exception as err:
print(err)
finally:
print("")
conn.close()
return None

函数管理 -> 触发管理

扫描器

#!/usr/bin/env python
# encoding: utf-8
import grequests
 
def main():
    serverless = ["https://service-xxx-xxx.sh.apigw.tencentcs.com/release/http_proxy"]
    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]
    try:
        ip = input("\033[31;32mPlease Input IP Address:\033[0m")
        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=5
                )
            )
            res_list = grequests.map(resp)
            for res in res_list:
                if res.text != "null" and res.text.find("errorCode") == -1:
                    print('[+]{}/tcp OPEN'.format(res.text))
    except Exception as err:
        print(err)
        pass
 
if __name__ == '__main__':
    main()

云函数目录扫描

选择Python3.6,3.7有问题。

# -*- coding: utf8 -*-
import requests
 
def main_handler(event, context):
    headers=event["headers"]
    url=event["queryString"]["url"]
    path = event["queryString"]["path"]
    crake_url=str(url+path)
    try:
        r = requests.get(crake_url,timeout=5,headers=headers,verify=False)
        status = r.status_code
    except Exception:
        status = None
        pass
 
    return status,crake_url

创建触发器为API

#!/usr/bin/env python
# encoding: utf-8
 
import random
import requests
 
def dict_read(dict_file, num):
    dict_list = []
    with open(dict_file, "r", encoding='utf-8') as ip_text:
        lines = ip_text.readlines()[:7] if num == 1 else ip_text.readlines()[7:]
        for line in lines:
            dict_list.append(line.strip("\n"))
    return dict_list
 
def main():
    from get_ua_header import UA
    number = 0
    severless = ["https://service-o1u1x736-1301587401.gz.apigw.tencentcs.com/release/dir_scan"]
    try:
        url = input("\033[31;32mplease input url:\033[0m")
        dict_file_path = input("\033[32;32mplease input crash dict path:\033[0m")
        print("")
        for server in severless:
            number += 1
            for path in dict_read(dict_file_path, number):
                headers = {
                    "User-Agent": random.choice(UA),
                }
                serverless_one = f"{server}?path={path}&url={url}"
                r = requests.get(serverless_one, headers=headers)
                print(r.text)
 
    except Exception as err:
        print(err)
 
if __name__ == '__main__':
    main()

云函数连接WebShell

# -*- coding: utf8 -*-
import requests
import json
def geturl(urlstr):
    jurlstr = json.dumps(urlstr)
    dict_url = json.loads(jurlstr)
    return dict_url['u']
def main_handler(event, context):
    url = geturl(event['queryString'])
    postdata = event['body']
    headers=event['headers']
    resp=requests.post(url,data=postdata,headers=headers,verify=False)
    response={
        "isBase64Encoded": False,
        "statusCode": 200,
        "headers": {'Content-Type': 'text/html;charset='+resp.apparent_encoding},
        "body": resp.text
    }
    return response

创建API触发器访问:

https://service-xxxx-xxxxx.gz.apigw.tencentcs.com/release/saulGoodman?u=http://111.111.111.111/shell.php

Last updated