SUCTF2025
Rev
SU_BBRE
给的是汇编,简单阅读一下,翻译如下
| 1 | 
 | 
可以得知以下信息:
- 输入的总长为19位
- 前16位输入用了function3和function4加密,不难看出是 RC4,key是suctf
- function1没有调用,但是里面有输入、提示信息以及8位的加密,可能需要将控制流转移到- function1
- function0用到了危险函数- strcpy,dest只有16位,而输入最多有19位,明显可以溢出,这溢出的3位刚好可以将控制流转到- function1,- function1地址为- 0x40223D,由于需要小端序则对应- 3D 22 40则溢出的三位转为字符为- ="@
| 1 | enc = [0x41,0x6d,0x62,0x4d,0x53,0x49,0x4e,0x29,0x28] | 
SUCTF{We1com3ToReWorld="@AndPWNT00}
SU_minesweeper
读入长度100
读入处理
这400位01代表是否有雷
读入的映射如下
根据这个扫雷
数字代表附近3*3区域有几颗雷,0xFF代表未知。
| 1 | [0x03, 0x04, 0xFF, 0xFF, 0xFF, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0x04, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x04, 0x06, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x05, 0x06, 0x04, 0xFF, 0x05, 0xFF, 0x04, 0x07, 0xFF, 0x08, 0xFF, 0x06, 0xFF, 0xFF, 0x06, 0x06, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0xFF, 0x03, 0xFF, 0x05, 0x06, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x05, 0x04, 0x05, 0x07, 0x06, 0xFF, 0xFF, 0x04, 0xFF, 0x02, 0x01, 0xFF, 0xFF, 0xFF, 0x03, 0x04, 0xFF, 0xFF, 0x05, 0x04, 0x03, 0xFF, 0xFF, 0x07, 0x04, 0x03, 0xFF, 0xFF, 0x01, 0x01, 0xFF, 0xFF, 0x04, 0x03, 0xFF, 0x02, 0xFF, 0x04, 0x03, 0xFF, 0xFF, 0x02, 0xFF, 0x05, 0x04, 0xFF, 0xFF, 0x02, 0x02, 0xFF, 0xFF, 0x04, 0xFF, 0x04, 0xFF, 0x03, 0x05, 0x06, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0x01, 0x04, 0xFF, 0xFF, 0x07, 0x05, 0xFF, 0xFF, 0x03, 0x03, 0x02, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0x05, 0x07, 0xFF, 0x03, 0x02, 0x04, 0x04, 0xFF, 0x07, 0x05, 0x04, 0x03, 0xFF, 0xFF, 0x04, 0xFF, 0x02, 0x04, 0x05, 0xFF, 0xFF, 0x06, 0x05, 0x04, 0xFF, 0x02, 0xFF, 0xFF, 0x07, 0x04, 0xFF, 0xFF, 0x03, 0xFF, 0x04, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x03, 0x02, 0x02, 0xFF, 0xFF, 0x02, 0x04, 0x03, 0x05, 0xFF, 0xFF, 0x05, 0xFF, 0x04, 0xFF, 0x06, 0xFF, 0xFF, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0xFF, 0x06, 0x06, 0xFF, 0x07, 0x06, 0x04, 0xFF, 0x04, 0x03, 0xFF, 0x04, 0x03, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x06, 0x07, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x05, 0xFF, 0x05, 0xFF, 0xFF, 0x06, 0x07, 0x07, 0xFF, 0x05, 0x06, 0x06, 0xFF, 0xFF, 0x02, 0x04, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0xFF, 0xFF, 0x07, 0x07, 0x06, 0xFF, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0x03, 0x05, 0xFF, 0x07, 0xFF, 0x05, 0xFF, 0x06, 0xFF, 0x05, 0xFF, 0xFF, 0x07, 0x08, 0xFF, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x05, 0x03, 0xFF, 0x04, 0x05, 0x05, 0x03, 0xFF, 0xFF, 0x06, 0x05, 0x05, 0x06, 0xFF, 0x06, 0x05, 0x02, 0x04, 0x03, 0x04, 0xFF, 0xFF, 0x03, 0x04, 0x04, 0x06, 0x05, 0xFF, 0x03, 0xFF, 0x05, 0x05, 0x05, 0xFF, 0xFF, 0x05, 0xFF, 0xFF, 0x04, 0xFF, 0xFF, 0x04, 0xFF, 0x07, 0x07, 0x08, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0xFF, 0xFF, 0xFF, 0x04, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x03] | 
约束处理如下
Z3求解即可,然后根据字符映射计算出正确输入,求MD5
| 1 | from z3 import * | 
SU_Harmony
鸿蒙安装包的逆向
文件结构如下
modules.abc和libs目录下的 so 文件应该比较重要,其他的应该是静态文件
这个.abc 应该对应的是安卓的 .dex
用基于 jadx 开发的 abc-decompiler 打开
EntryAbility和EntryBackupAbility里没看到什么验证代码或者加密,看看pages目录下的Index
可以快速定位到一个输入的验证函数,可以看到是调用了libentry.so的check函数
那我们用 IDA 打开 libentry.so看看
搜索字符串定位check函数,是sub_3750
又很多混淆,但是很多都是重复的,可以忽略,获取一些关键信息
长度为32
这里将输入经过sub_57B0加密后和密文进行比较
sub_57B0调用了几个函数进行加密,这几个函数也都有混淆,其实分析完会发现就是个大数运算
我们一个个函数分析,只看关键部分就行
sub_62F0大概就是将输入都转成字符的数字
sub_6D20应该就是个乘法,根据sub_57B0中的调用,两个参数是一样的,所以这一步是平方
sub_8270将两个参数逐位相乘,存入第三个参数中,根据sub_57B0中的调用,就是乘以2
sub_9890应该就是个加法,根据sub_57B0中的调用,是将平方的结果和乘以2的结果相加
sub_A8F0,应该是将两个参数相减,根据调用,就是减3
sub_C160是个除法,根据调用就是除以2
所以总结一下,就是计算方程(x^2+x*2-3)/2=enc即(x+1)^2=2*enc+4
| 1 | import math | 
SU_mapmap2
字符串定位到关键函数,简单理解一下,要求输入长度268
根据限制条件,限制了字符只能是aswd,同时从内存0x63F530和0x63F538中定义了起始和终止状态
向四个方向移动,如果合法更新状态,否则回到初始状态
本来想动调看能不能导出地图,手动走的,调半天没调出来。可以看看出题人的方法
函数sub_4631C2和函数sub_4632EE里有一堆的嵌套调用,比较复杂,动调应该可以找到并模拟出来逻辑
可以尝试另一种方式,用idapython的continue_process()和wait_for_next_event(WFNE_SUSP, -1)来实现自动调试。
- continue_process()IDA API中的函数,用于继续执行被调试的程序,相当于调试器中按F9继续运行的操作程序会一直运行,直到遇到下一个断点或异常
- wait_for_next_event(WFNE_SUSP, -1)用于等待下一个调试事件发生 ,- WFNE_SUSP是一个标志,表示等待程序暂停事件 ,- -1参数表示无限等待,直到事件发生
我们在for循环中下断点,获取以下三个地址的内容,用于每次设置状态
| 1 | input_addr = rbp - 0x40 | 
DFS搜索即可
| 1 | from typing import Dict | 
MD5












































