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