Hello Navi

Tech, Security & Personal Notes

Challenge

"Can you see the light?" — 2-level encoding challenge。页面显示 3 段大二进制数据,分别用 RGB 三种颜色渲染。

Solution

颜色提示了处理方法:三种颜色通道是三个独立的二进制序列,需要做位运算组合。

Level 1 — OR

将三个颜色通道的二进制逐 bit 做 OR(或)运算:只要任意一个颜色在该 bit 为 1,结果就为 1。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ python3
# 三个颜色块的二进制数据(全部拼接)
>>> red = '000000000110000001100000000000000000000001000000...'
>>> green = '010000010110100000100000000000000000000000000001...'
>>> blue = '010000010100000001100001001000010010000000001000...'
# 逐 bit OR
>>> result = ''
>>> for i in range(len(red)):
... result += '1' if int(red[i]) | int(green[i]) | int(blue[i]) else '0'
...
# 按 8-bit 转 ASCII
>>> ''.join(chr(int(result[i:i+8], 2)) for i in range(0, len(result), 8))
'Aha! It seems you got something interesting!\nWell to go to the next stage, go there:\n01001100011...'

OR 的结果是一段提示文本 + 4 行二进制串。将那 4 个二进制串按 8-bit 解码:

1
2
3
4
01001100011010010110011101101000  ->  Ligh
00110111010111110100110001100101 -> 7_Le
01110110011001010110110000110010 -> vel2
00101110011100000110100001110000 -> .php

得到文件名 Ligh7_Level2.php。访问 http://www.wechall.net/challenge/anto/enlightment/Ligh7_Level2.php 进入 Level 2。

Level 2 — XOR

Level 2 页面使用 CMY(Cyan, Magenta, Yellow)三色渲染另一组二进制数据。这次需要用 XOR(异或)运算:

1
2
3
4
5
6
7
8
$ python3
# 逐 bit XOR
>>> result = ''
>>> for i in range(len(cyan)):
... result += '1' if int(cyan[i]) ^ int(magenta[i]) ^ int(yellow[i]) else '0'
...
>>> ''.join(chr(int(result[i:i+8], 2)) for i in range(0, len(result), 8))
'Triple-X-OR, right?\nGreat! Here is what you should be looking for..."Gimme_Da_Light"'

最终答案在消息末尾。

Gimme_Da_Light

Challenge

Digraph substitution cipher — 每个明文字母编码为 2 个字符的 pair。密文保留原始空格分词,无换行。明文是标准英文,含大小写和标点。

密文约 290 字符,136 个 digraph pair,30 个唯一 digraph(26 字母 + 4 标点 !?.:)。映射关系和密码随 session 变化。

这是同音 cipher — 同一字母可能对应多个 digraph(例如 cvxl 都映射到 cqnhc 都映射到 e)。这意味着纯频率分析无法唯一确定映射,需要结合词结构消歧。

Solution

第一步:识别标点 digraph

密文保留空格分词,标点出现在词尾。22 个词的固定结构:

1
2
3
4
5
6
词 0  "congratulations!"  → 末尾 digraph = '!'
词 5 "successfully!" → 末尾 digraph = '!'(应与词 0 相同)
词 10 "either." → 末尾 digraph = '.'
词 12 "it?" → 末尾 digraph = '?'
词 13 "well." → 末尾 digraph = '.'(应与词 10 相同)
词 20 "solution:" → 末尾 digraph = ':'

第二步:用词结构逐步还原字母映射

词 0 "congratulations!" 是关键锚点 — 16 个 digraph 对应 16 个字符,且字母重复模式固定(a 出现 2 次、t 2 次、o 2 次、n 2 次)。对齐后直接得到 12 个字母映射。

然后用短词交叉验证:

1
2
3
4
5
6
7
词 19 "as"           → 2 digraph,与词 20 首字母共享
词 20 "solution:" → 9 digraph,末尾是 ':'
词 1 "?ou" → "you" → 第 1 个 digraph = 'y'
词 3 "t?is" → "this" → 第 2 个 digraph = 'h'
词 6 "?as" → "was" → 第 1 个 digraph = 'w'
词 7 "not" → 直接验证 n/o/t 映射
词 8 "too" → 验证 'o' 的双字母模式

逐步扩展到全部 30 个 digraph。

第三步:模拟退火(备选/验证)

纯频率分析 + 模拟退火也能解,但单独使用收敛较慢(同音 cipher 导致多个等价映射)。词结构推导出部分映射后,用模拟退火补全剩余未知 digraph 更实用。

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
29
30
31
import random, math

eng_freq = {'e':.127,'t':.091,'a':.082,'o':.075,'i':.070,'n':.067,
's':.063,'h':.061,'r':.060,'d':.043,'l':.040}

def score_word(word):
clean = word.rstrip('!.,?:').lower()
s = sum(eng_freq.get(c, 0) * 2 for c in clean)
common = {'the':5,'and':5,'was':5,'not':5,'too':5,'you':5,'this':5,
'it':5,'as':5,'is':5,'congratulations':10,'decrypted':10,
'successfully':10,'difficult':10,'keyword':10,'solution':10}
return s + common.get(clean, 0)

def solve_sa(digraphs, chars, words, n_iter=100000, n_restarts=20):
best_mapping, best_score = None, -1
for _ in range(n_restarts):
m = dict(zip(digraphs, random.sample(chars, len(digraphs))))
sc = sum(score_word(decode(m, w)) for w in words)
t = 5.0
for _ in range(n_iter):
d1, d2 = random.sample(digraphs, 2)
m[d1], m[d2] = m[d2], m[d1]
ns = sum(score_word(decode(m, w)) for w in words)
if ns > sc or random.random() < math.exp((ns - sc) / max(t, 0.01)):
sc = ns
if sc > best_score:
best_score, best_score = sc, dict(m)
else:
m[d1], m[d2] = m[d2], m[d1]
t *= 0.99995
return best_mapping

实测:20 次重启 × 100k 迭代,约 2 分钟,不一定收敛到正确明文。词结构推导秒出结果。

第四步:提取密码

明文末尾格式:enter this keyword as solution: [PASSWORD]!

密码在 solution: 后、! 前。提交时去掉末尾 !(它是明文标点,不是密码的一部分)。

注意事项: - 同音 cipher:同一字母可能对应多个 digraph,不能假设一一对应 - 密码随 session 变化,每次访问页面重新生成

Challenge

一个有 SQL 注入漏洞的 PHP 脚本,in_array() 白名单检查可被绕过。要求提供最短的修复(least effort fix)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$whitelist = array(1, 2, 3);
if (false === ($show = isset($_GET['show']) ? $_GET['show'] : false)) {
die('MISSING PARAMETER; USE foo.bar?show=[1-3]');
}
elseif (in_array($show, $whitelist)){
$query = "SELECT 1 FROM `table` WHERE `id`=$show";
echo 'Query: '.htmlspecialchars($query, ENT_QUOTES).'<br/>';
die('SHOWING NUMBER '.htmlspecialchars($show, ENT_QUOTES));
}
else {
die('HACKER NONONO');
}
?>

Solution

漏洞分析: in_array() 默认使用 loose comparison(==)。白名单是整数 1, 2, 3,而输入 "1 union select 1" 通过 == 比较时会先转为整数:"1 union select 1" == 1 → true。因此 whitelist 检查被绕过,$show 仍然带着完整注入字符串进入 SQL 查询。

最短修复:

挑战要求「least effort」——在代码的某个逻辑位置增加最少字符来修复漏洞。

有两种 2 字符的方案:

  • 1* — 将 SQL 改为 WHERE \id`=1*\(show`,在 SQL 层面做乘法运算强制 `\)show` 转为数字
  • -0 — 将 SQL 改为 WHERE \id`=$show-0`,减法运算同样强制转为数字

两种都只增加 2 个字符,比 (int)$show(4 字符)或 in_array($show, $whitelist, true)(6 字符)更短。

漏洞页面接受 answer 字段提交,cmd=Fix+It,不需要 CSRF token。

1*

Challenge

利用一行有 XSS 漏洞的 PHP 代码。目标是找到漏洞点并提交修复方案。

1
echo "<a href='http://".htmlspecialchars(Common::getPost('input'))."'>Exploit Me</a>";

Solution

漏洞分析: htmlspecialchars() 的默认模式是 ENT_COMPAT,只转义双引号 "(转为 &quot;),不转义单引号 '。而 href 属性值恰好用单引号包裹,因此可以通过单引号逃逸出属性值,注入 XSS 事件。

第一步 — 漏洞利用:

在 input 中输入一个单引号闭合 href,然后注入事件处理属性:

1
' onmouseover='alert(1)

生成的 HTML:

1
<a href='http://' onmouseover='alert(1)'>Exploit Me</a>

注意三个单引号的闭合逻辑: - href='http:// 为 HTML 模板的开头部分 - 第一个 ' 闭合了 href 的起始单引号 - onmouseover='alert(1)' 被解析为新的 HTML 属性 - 最后的 '> 会落在属性值的单引号后面(不闭合也不影响渲染)

悬停在链接上就会触发 onmouseover。在 WeChall 自己的测试页面里,鼠标悬停就能看到 alert 弹窗。

第二步 — 修复:

htmlspecialchars() 加上 ENT_QUOTES 标志,使单引号也被转义:

1
echo "<a href='http://".htmlspecialchars(Common::getPost('input'), ENT_QUOTES)."'>Exploit Me</a>";

加上 ENT_QUOTES 后,输入 ' 会被转为 &#039;,无法再逃逸 href 属性。

提交方式: POST 到 htmlspecialchars.php,字段名为 solution(不是 answer),cmd=Submit。需要 CSRF token。

echo Exploit Me;

Challenge

PHP type juggling 挑战。源码要求输入一个 "magic number",不能包含数字 1-9,但必须等于 3735929054。

Solution

源码关键逻辑:

1
2
3
4
5
6
7
8
9
10
11
function noother_says_correct($number) {
$one = ord('1');
$nine = ord('9');
for ($i = 0; $i < strlen($number); $i++) {
$digit = ord($number[$i]);
if (($digit >= $one) && ($digit <= $nine)) {
return false; // 禁止数字 1-9
}
}
return $number == "3735929054"; // loose comparison
}

数字 0 是允许的(只检查 1-9)。3735929054 的十六进制是 0xdeadc0de,不包含 1-9。

PHP 的 loose comparison (==) 遇到 0x 前缀的字符串时,PHP 7.x 及更早版本会将其按十六进制解析为整数。所以 "0xdeadc0de" == "3735929054"3735929054 == 3735929054true

这个技巧在 PHP 8.0+ 已被修复(hex string 不再被当作 numeric string),但 WeChall 仍运行在旧版 PHP 上。

1
2
$ python3 -c "print(0xdeadc0de)"
3735929054

提交入口在 php0818.php,POST 字段为 number(不是 answer,也不需要 CSRF token)。

0xdeadc0de

Challenge

在本机或公网服务器搭建 HTTP 服务器,从外部可访问,提供指定路径和内容的文件。WeChall 会从你登录时的来源 IP 发起回调验证。

挑战页面会给出具体的参数(每个 session 不同):

  • URL 路径: http://<IP>:<port>/<USER>/<USER>.html
  • 文件内容: My name is <USER> and iChall.(精确字节数)
  • 字节数要求精确,不能多换行符

Solution

核心问题: WeChall 根据你登录时的来源 IP 发起回调验证。如果你的机器在 NAT/VPN 后面没有公网 IP,就无法直接验证。

解决方案: 在一台有公网 IP 的服务器上(VPS)搭建 Web 服务,从该服务器登录 WeChall 并提交。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 1. 在公网服务器上创建文件(USER 替换为 challenge 页面给你的值)
mkdir -p /tmp/<USER>
echo -n 'My name is <USER> and iChall.' > /tmp/<USER>/<USER>.html

# 2. 启动 HTTP 服务器
cd /tmp && python3 -m http.server <PORT> &

# 3. 用 Python 从服务器登录 WeChall 并提交端口
python3 -c "
import urllib.request, urllib.parse, http.cookiejar

cj = http.cookiejar.MozillaCookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
opener.addheaders = [('User-Agent', 'Mozilla/5.0')]

# Login (填入自己的 WeChall 账号)
opener.open('https://www.wechall.net/en/login', timeout=30)
data = urllib.parse.urlencode({'username':'<WC_USER>','password':'<WC_PASS>','login':'Login'}).encode()
opener.open(urllib.request.Request('https://www.wechall.net/en/login', data=data), timeout=30)

# Submit port
data = urllib.parse.urlencode({'port':'<PORT>','go':'I have set it up. Please check my server.'}).encode()
opener.open(urllib.request.Request('https://www.wechall.net/en/challenge/training/www/basic/index.php', data=data), timeout=30)
"

Challenge

Help! A zebra escaped from its enclosure. But where is it now?

一张 PNG 图片(斑马),斑马身上的条纹实际上是一个一维条码(barcode),但条码的条纹"越狱"了——bars 没有延伸到应有的边界。

Solution

条码的黑色条纹只在斑马身上,没有延伸到上下边界("escaped from its enclosure"),所以 zbarimg 等工具直接解码会失败。

第一步,提取斑马条纹区域。用 Python 垂直平均条纹区域,再按阈值二值化,模拟"补全"条纹的效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from PIL import Image
import numpy as np

img = Image.open('zebra.png')
arr = np.array(img)

# 取条纹密集区域 (y=46~258)
region = arr[46:258, :, :3].mean(axis=2)

# 每列判断:若超过 40% 像素是暗色,则该列算黑条
col_dark = np.mean(region < 128, axis=0) > 0.4

# 生成条码图像
barcode = np.ones((100, len(col_dark) + 40), dtype=np.uint8) * 255
barcode[:, 20:-20] = (1 - col_dark.astype(np.uint8)) * 255

# 放大以使解码器识别
h, w = barcode.shape
big = np.repeat(np.repeat(barcode, 4, axis=0), 2, axis=1)
Image.fromarray(big).save('zebra_fixed.png')

然后用 zbarimg 解码:

1
2
$ zbarimg -S*.enable zebra_fixed.png
QR-Code:The answer is saFFari

关键词就是 saFFari(斑马跑到 Safari 上了 🦓)。

saFFari

Challenge

Bacon's cipher (Baconian cipher). A hidden message is encoded in the case pattern of a paragraph of text. Each letter is represented by 5 bits of A/B (upper/lower case). Uses the full 26-letter Bacon alphabet.

The page displays a Wikipedia article about Bacon's cipher with mixed case — the case pattern hides a secret message.

Solution

提取大小写模式,Upper=B,Lower=A,每 5 位一组按 26 字母 Bacon 字母表映射回 A-Z。空格用 X 表示。

1
BaCoN's cIphEr or THE bacOnIAN CiPHer iS a meThOD oF sTEGaNOGrapHY (a METhoD Of HidIng A sECRet MeSsaGe as OpPOsEd TO a TRUe CiPHeR) dEVIseD BY francis bAcoN. a MessAge Is coNCeALED in THe pRESenTatIoN OF TexT, ratHer thaN iTs coNteNt. tO enCODe A MEsSaGe, eaCh lETter Of THe pLAInText Is rePLAcED By A groUp oF fIvE OF the LETterS 'A' or 'B'. thIs REplaCement is dONE aCcordINg To tHe ALphAbet Of THe BACOnIAN cIpHeR, sHoWn bElOw. NoTe: A SeCoNd vErSiOn oF BaCoN'S CiPhEr uSeS A UnIqUe cOdE FoR EaCh lEtTeR. iN OtHeR WoRdS, i aNd j eAcH HaS ItS OwN PaTtErN. tHe wRiTeR MuSt mAkE UsE Of tWo dIfFeReNt tYpEfAcEs fOr tHiS CiPhEr. AfTeR PrEpArInG A FaLsE MeSsAgE WiTh tHe sAmE NuMbEr oF LeTtErS As aLl oF ThE As aNd bS In tHe rEaL, sEcReT MeSsAgE, tWo tYpEfAcEs aRe cHoSeN, oNe tO RePrEsEnT As aNd tHe oThEr bS. tHeN EaCh lEtTeR Of tHe fAlSe mEsSaGe mUsT Be pReSeNtEd iN ThE ApPrOpRiAtE TyPeFaCe, AcCoRdInG To wHeThEr iT StAnDs fOr aN A Or a b. To dEcOdE ThE MeSsAgE, tHe rEvErSe mEtHoD Is aPpLiEd. EaCh 'TyPeFaCe 1' LeTtEr iN ThE FaLsE MeSsAgE Is rEpLaCeD WiTh aN A AnD EaCh 'TyPeFaCe 2' LeTtEr iS RePlAcEd wItH A B. tHe bAcOnIaN AlPhAbEt iS ThEn uSeD To rEcOvEr tHe oRiGiNaL MeSsAgE. aNy mEtHoD Of wRiTiNg tHe mEsSaGe tHaT AlLoWs tWo dIsTiNcT RePrEsEnTaTiOnS FoR EaCh cHaRaCtEr cAn bE UsEd fOr tHe bAcOn cIpHeR. bAcOn hImSeLf pRePaReD A BiLiTeRaL AlPhAbEt[2] FoR HaNdWrItTeN CaPiTaL AnD SmAlL LeTtErS WiTh eAcH HaViNg tWo aLtErNaTiVe fOrMs, OnE To bE UsEd aS A AnD ThE OtHeR As b. ThIs wAs pUbLiShEd aS An iLlUsTrAtEd pLaTe iN HiS De aUgMeNtIs sCiEnTiArUm (ThE AdVaNcEmEnT Of lEaRnInG). BeCaUsE AnY MeSsAgE Of tHe rIgHt lEnGtH CaN Be uSeD To cArRy tHe eNcOdInG, tHe sEcReT MeSsAgE Is eFfEcTiVeLy hIdDeN In pLaIn sIgHt. ThE FaLsE MeSsAgE CaN Be oN AnY ToPiC AnD ThUs cAn dIsTrAcT A PeRsOn sEeKiNg tO FiNd tHe rEaL MeSsAgE.

解码:

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
import re

text = """
BaCoN's cIphEr or THE bacOnIAN CiPHer iS a meThOD oF sTEGaNOGrapHY (a METhoD Of HidIng A sECRet MeSsaGe as OpPOsEd TO a TRUe CiPHeR) dEVIseD BY francis bAcoN. a MessAge Is coNCeALED in THe pRESenTatIoN OF TexT, ratHer thaN iTs coNteNt. tO enCODe A MEsSaGe, eaCh lETter Of THe pLAInText Is rePLAcED By A groUp oF fIvE OF the LETterS 'A' or 'B'. thIs REplaCement is dONE aCcordINg To tHe ALphAbet Of THe BACOnIAN cIpHeR, sHoWn bElOw. NoTe: A SeCoNd vErSiOn oF BaCoN'S CiPhEr uSeS A UnIqUe cOdE FoR EaCh lEtTeR. iN OtHeR WoRdS, i aNd j eAcH HaS ItS OwN PaTtErN. tHe wRiTeR MuSt mAkE UsE Of tWo dIfFeReNt tYpEfAcEs fOr tHiS CiPhEr. AfTeR PrEpArInG A FaLsE MeSsAgE WiTh tHe sAmE NuMbEr oF LeTtErS As aLl oF ThE As aNd bS In tHe rEaL, sEcReT MeSsAgE, tWo tYpEfAcEs aRe cHoSeN, oNe tO RePrEsEnT As aNd tHe oThEr bS. tHeN EaCh lEtTeR Of tHe fAlSe mEsSaGe mUsT Be pReSeNtEd iN ThE ApPrOpRiAtE TyPeFaCe, AcCoRdInG To wHeThEr iT StAnDs fOr aN A Or a b. To dEcOdE ThE MeSsAgE, tHe rEvErSe mEtHoD Is aPpLiEd. EaCh 'TyPeFaCe 1' LeTtEr iN ThE FaLsE MeSsAgE Is rEpLaCeD WiTh aN A AnD EaCh 'TyPeFaCe 2' LeTtEr iS RePlAcEd wItH A B. tHe bAcOnIaN AlPhAbEt iS ThEn uSeD To rEcOvEr tHe oRiGiNaL MeSsAgE. aNy mEtHoD Of wRiTiNg tHe mEsSaGe tHaT AlLoWs tWo dIsTiNcT RePrEsEnTaTiOnS FoR EaCh cHaRaCtEr cAn bE UsEd fOr tHe bAcOn cIpHeR. bAcOn hImSeLf pRePaReD A BiLiTeRaL AlPhAbEt[2] FoR HaNdWrItTeN CaPiTaL AnD SmAlL LeTtErS WiTh eAcH HaViNg tWo aLtErNaTiVe fOrMs, OnE To bE UsEd aS A AnD ThE OtHeR As b. ThIs wAs pUbLiShEd aS An iLlUsTrAtEd pLaTe iN HiS De aUgMeNtIs sCiEnTiArUm (ThE AdVaNcEmEnT Of lEaRnInG). BeCaUsE AnY MeSsAgE Of tHe rIgHt lEnGtH CaN Be uSeD To cArRy tHe eNcOdInG, tHe sEcReT MeSsAgE Is eFfEcTiVeLy hIdDeN In pLaIn sIgHt. ThE FaLsE MeSsAgE CaN Be oN AnY ToPiC AnD ThUs cAn dIsTrAcT A PeRsOn sEeKiNg tO FiNd tHe rEaL MeSsAgE.
"""

# 只取字母,忽略标点和空格
bits = ''.join('B' if c.isupper() else 'A'
for c in text if c.isalpha())

bac26 = {'AAAAA':'A','AAAAB':'B','AAABA':'C','AAABB':'D',
'AABAA':'E','AABAB':'F','AABBA':'G','AABBB':'H',
'ABAAA':'I','ABAAB':'J','ABABA':'K','ABABB':'L',
'ABBAA':'M','ABBAB':'N','ABBBA':'O','ABBBB':'P',
'BAAAA':'Q','BAAAB':'R','BAABA':'S','BAABB':'T',
'BABAA':'U','BABAB':'V','BABBA':'W','BABBB':'X',
'BBAAA':'Y','BBAAB':'Z'}

decoded = ''
# 截断到 5 的倍数,忽略末尾不足 5 位的碎片
for i in range(0, len(bits) - len(bits) % 5, 5):
c = bac26.get(bits[i:i+5], '?')
if c == 'X':
decoded += ' '
else:
decoded += c

print(decoded)

解码后得到类似:

1
VERY WELL DONE FELLOW HACKER THE SECRET KEYWORD IS DRSLCAHINFSF

注意:该挑战是 session-bound(每 session 密码不同),上述消息只是示例。实际运行脚本会得到当前 session 的密码,形如 bpnnbnfonec

关键点:

  • 使用 26 字母版本(I/J 各有独立编码)
  • case 映射为 Upper=B, Lower=A
  • X 代表空格(word separator)

Challenge

管理员根据 feedback "修复" 了上一个版本(Limited Access)中的 .htaccess,现在 protected/protected.php 更加安全了。需要再次访问它。

Solution

上一个版本用 <Limit GET> 限制了 GET 方法,通过改用 POST 绕过。这个"修复"版本在 .htaccess 里封了更多方法:

1
2
3
<Limit GET POST HEAD PUT DELETE CONNECT OPTIONS PATCH>
require valid-user
</Limit>

Apache 的 <Limit> 指令只拦截明确列出的方法,未列出的方法不受限制。上面漏掉了 TRACKPATCHPROPFINDMOVE 等非标准扩展方法。

直接用 TRACK 方法绕过:

1
2
$ curl -X TRACK -b 'WC=...' \
'https://www.wechall.net/en/challenge/wannabe7331/limited_access_too/protected/protected.php'

返回受保护页面的内容,挑战即完成(auto-solve,无需额外提交)。

Challenge

A regular square pyramid where all 8 edges are equal in length (set to a). Find a formula for the volume (no more than 9 characters).

Solution

正四棱锥,所有 8 条棱等长(设为 a)。求体积公式(不大于 9 字符)。

底面正方形对角线 \(d = a\sqrt{2}\),底面中心到顶点距离为 \(d/2 = a\sqrt{2}/2\)

\(h = \sqrt{a^2 - (a\sqrt{2}/2)^2} = \sqrt{a^2 - a^2/2} = a/\sqrt{2}\)

体积 \(V = \frac{1}{3} \times a^2 \times h = \frac{1}{3} \times a^2 \times \frac{a}{\sqrt{2}} = \frac{a^3}{3\sqrt{2}}\)

化简到 9 字符以内:

\[ \frac{a^3}{3\sqrt{2}} = \frac{a^3}{\sqrt{18}} = 18^{-\frac{1}{2}} \cdot a^3 \]

提交 \(18^{-0.5}a^3\) 即可(9 字符,精确解):

18-.5a3
+ + +
SYSTEM STATUS: ACTIVE ENCRYPTED SECTOR 7 PRTS_TERMINAL_V2.0 PROTOCOL: 0x2A ENCRYPTED DATA STREAM SYSTEM: ONLINE