XCTF-LilacCTF2026Ezpython

admin 2026-01-30 17:49:43 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: ThisdocumentdetailsawriteupfortheXCTF-LilacCTF2026Ezpythonchallenge.TheauthordemonstrateshowtoextractanddecompileanencryptedPythonEXEusingPyInstallerandpycdctorecoverthesourcecode.ThecoreanalysisrevealsaBTEAencryptionalgorithmusedtovalidatetheflag.Theauthorexplainsthelogicinvolvingstructpackingandkeyderivation,thenprovidesaPythonexploitscripttoreversetheBTEAencryptionandsuccessfullyretrievetheflag.ThisservesasapracticalguideforreverseengineeringPythonexecutablesandsolvingcrypto-reversingtasksinCTFs. 综合评分: 89 文章分类: CTF,逆向分析,二进制安全


cover_image

XCTF-LilacCTF 2026 Ezpython

Mystery Mystery

赛查查

2026年1月30日 10:09 北京

提示如下

Python is not as difficult as you think

flag format: LilacCTF{…}

下载附件不难看见这个exe已经被加密

接着我们去进行给他转成Pyc进行解密

解包工具

 PyInstaller onefile

成功进行解密 接着我们去找他的原Pyc文件进行转成python、

这里给大家介绍两款实用工具

1.在线工具:python反编译 – 在线工具

2.离线工具:【免费下载】 pycdc:强大的Python反编译工具-CSDN博客

import&nbsp;structfrom&nbsp;crypto&nbsp;import&nbsp;*from&nbsp;sys&nbsp;import&nbsp;*import&nbsp;base64import&nbsp;myalgowelcome_msg =&nbsp;'V2VsYzBtMyBUbyBUaGUgV29ybGQgb2YgTDFsYWMgPDM='input_msg =&nbsp;':i(G#8T&KiF<F_)F`JToCggs;'right_msg =&nbsp;'UmlnaHQsIGNvbmdyYXR1bGF0aW9ucyE='wrong_msg =&nbsp;'V3JvbmcgRmxhZyE='print(b64decode(welcome_msg).decode())flag =&nbsp;input(a85decode(input_msg).decode())if&nbsp;not&nbsp;(flag.startswith('LilacCTF{')&nbsp;and&nbsp;flag.endswith('}')&nbsp;and&nbsp;(len(flag) ==&nbsp;26)):&nbsp; &nbsp;&nbsp;print(b64decode(wrong_msg).decode())else:&nbsp; &nbsp; flag = flag[9:25]&nbsp; &nbsp; res = [761104570,&nbsp;1033127419,&nbsp;3729026053,&nbsp;795718415]&nbsp; &nbsp; key = struct.unpack('<IIII',&nbsp;b'1111222233334444')&nbsp; &nbsp;&nbsp;input&nbsp;=&nbsp;list(struct.unpack('<IIII', flag.encode()))&nbsp; &nbsp; myalgo.btea(input,&nbsp;4, key)&nbsp; &nbsp;&nbsp;if&nbsp;input[0] == res[0]&nbsp;and&nbsp;input[1] == res[1]&nbsp;and&nbsp;(input[2] == res[2])&nbsp;and&nbsp;(input[3] == res[3]):&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(b64decode(right_msg).decode())&nbsp; &nbsp;&nbsp;else:&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(b64decode(wrong_msg).decode())

转成py文件进行代码审计

首先看见base解密以及ASCll85解密

接着我们进行一一解密首先的是

第一段解密welcome_msg = 'V2VsYzBtMyBUbyBUaGUgV29ybGQgb2YgTDFsYWMgPDM='解密:Welc0m3 To The World of L1lac <3第二段解密input_msg = ':i(G#8T&KiF<F_)F`JToCggs;'解密:Plz Input Your Flag:第三段解密right_msg = 'UmlnaHQsIGNvbmdyYXR1bGF0aW9ucyE='解密:Right, congratulations!第四段解密解密:Wrong Flag!

接着往下看

这里可以看出flag必须以 LilacCTF{ 开头,以} 结尾总长度必须等于 26

随后做切片flag = flag[9:25] ,因此实际参与加密校验的内容长度是

26&nbsp;-&nbsp;9&nbsp;-&nbsp;1&nbsp;=&nbsp;16个字符

也就是大括号内恰好16个字符并且由于flag.encode(),想要恰好16字节,基本意味着必须是 ASCII 单字节字符集

接着往下可关键

关键密码学点:把 16 字节当作 4×uint32

input&nbsp;= list(struct.unpack('<IIII', flag.encode()))关键点<IIII':小端序解析4个32-bit 无符号整数这一步强制 flag.encode() 必须 正好 16 字节,否则 struct.unpack 直接异常

同理,key固定 16 字节 key,解析成4个uint32小端字

key&nbsp;= struct.unpack('<IIII', b'1111222233334444')

核心校验:BTEA比较结果

myalgo.btea(input,&nbsp;4, key)if&nbsp;input&nbsp;== res:&nbsp;print("Right")

btea(v, n, k) 常见约定:n>1 表示加密,n<-1 表示解密

这里 n=4,说明把 4-word(128-bit)块做 BTEA 运算后,结果必须精确等于

res&nbsp;= [761104570,&nbsp;1033127419,&nbsp;3729026053,&nbsp;795718415]

因此考点为:逆向/还原myalgo.btea的实现细节,以及 32 位无符号溢出取模 2^32。

参考链接如下

XXTEA - Wikipediahttps://ctf.thaysan.com/ctf-and-writeups/2024-or-htb-cyber-apocalypse-challenges/cryptographie/iced-tea?utm_source=chatgpt.comhttps://ctftime.org/writeup/32328?utm_source=chatgpt.com

接着写一个EXP

import&nbsp;struct
DELTA&nbsp;=&nbsp;0x45555254MASK&nbsp; =&nbsp;0xFFFFFFFF
def&nbsp;_mx(y, z, s, k, p, e):&nbsp; &nbsp;&nbsp;a&nbsp;= ((z <<&nbsp;3) ^ (y >>&nbsp;5)) + ((y <<&nbsp;4) ^ (z >>&nbsp;2))&nbsp; &nbsp;&nbsp;b&nbsp;= (s ^ y) + (k[(p &&nbsp;3) ^ e] ^ z)&nbsp; &nbsp;&nbsp;return&nbsp;a ^ b
def&nbsp;btea_dec_4(block, key):&nbsp; &nbsp;&nbsp;v&nbsp;= list(block) &nbsp;# work&nbsp;on&nbsp;a copy&nbsp; &nbsp;&nbsp;rounds&nbsp;=&nbsp;6&nbsp;+&nbsp;52&nbsp;//&nbsp;4&nbsp; &nbsp;&nbsp;s&nbsp;= (rounds * DELTA) & MASK
&nbsp; &nbsp;&nbsp;for&nbsp;_ in range(rounds):&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;e&nbsp;= (s >>&nbsp;2) &&nbsp;3&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;y&nbsp;= v[0]
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;for&nbsp;p in range(3,&nbsp;0, -1): &nbsp;#&nbsp;3,2,1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;z&nbsp;= v[p -&nbsp;1]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;v[p] = (v[p] - _mx(y, z, s, key, p, e)) & MASK&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;y&nbsp;= v[p]
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;z&nbsp;= v[3]&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;v[0] = (v[0] - _mx(y, z, s, key,&nbsp;0, e)) & MASK&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;s&nbsp;= (s - DELTA) & MASK
&nbsp; &nbsp;&nbsp;return&nbsp;v
def&nbsp;main():&nbsp; &nbsp;&nbsp;ct&nbsp; =&nbsp;[761104570, 1033127419, 3729026053, 795718415]&nbsp; &nbsp;&nbsp;key&nbsp;= list(struct.unpack("<4I", b"1111222233334444"))&nbsp; &nbsp;&nbsp;pt&nbsp; = struct.pack("<4I", *btea_dec_4(ct, key)).decode("ascii")&nbsp; &nbsp;&nbsp;print(f"LilacCTF{{{pt}}}")
if&nbsp;__name__ ==&nbsp;"__main__":&nbsp; &nbsp;&nbsp;main()

打印flag即可

来源:小M安全

精选阅读

交流分享


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:赛查查 Mystery Mystery《XCTF-LilacCTF 2026 Ezpython》

评论:0   参与:  0