2024DASCTFXHDCTFFinalEncrypt
0x00 分析给了三个文件,一个程序,两个.enc结尾的,应该是加密了
后面要爆破时间戳
主打一个写代码
0x01 解无壳,直接上IDA
main函数直接给出,一步步分析
接收输入然后根据输入的命令执行不同操作
具体操作可以查看printHelp函数
12345678910111213"Usage: FinalEncrypt [OPTIONS]...\n""Encrypts/Decrypts files using FinalEncrypt\n""\n"" -h Prints help screen\n"" -e [filename] Encrypts a specified file (must be passed with -r)\n"" -d [filename] Decrypts a specified file (must be passed with -k)\n" ...
2024DASCTFXHDCTFbaby_rop
0x00 分析ROP技术:
ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防御(比如内存不可执行和代码签名等)。通过上一篇文章栈溢出漏洞原理详解与利用,我们可以发现栈溢出的控制点是ret处,那么ROP的核心思想就是利用以ret结尾的指令序列把栈中的应该返回EIP的地址更改成我们需要的值,从而控制程序的执行流程。
这题有SMC那味了
程序流动调看
0x01 解进入main函数,发现只有一个vuln函数
跟进去可以发现调用了一个read函数
看不太懂,直接断在call read处后向下走
之后调用retn会发现执行到了这个地方
之后不停执行pop和retn,目的将栈中的数据放入寄存器中
之后到了这个函数
关于mmap可以看这个:linux库函数mmap()原理及用法详解
之后继续执行会到mprotect函数
关于mprotect可以看这个:Linux中mprotect()函数的用法
这两个连在一起用:通过mmap&mprotect来绕过nx
继续执行会回到一次read函数 ...
2024RCTFbloker_vm
0x00 题目分析父进程开启一个子进程并接收子进程的异常信息,根据这些信息来执行程序流
由于这个开启的子进程是它本身,所以子进程的代码实际上是可以在程序中找到的(不过加了密,需要dump下来解密先)
但实际上没有必要去看子进程的解密结果,只要直接调父进程就可以就可以得到程序的执行流程了
0x01 解无壳,直接拖IDA
符号加载还算比较完全,基本可以看懂在干什么,这个A10就是主函数
因为opcode不能直接获取,所以这题动调才能搞清楚流程
注意限制了输入长度
之后单步调试可以发现到了这个地方
关于ReadProcessMemory可以看微软的文档
查看ProcessInformation可以发现这个ReadProcessMemory的目标就是与题目同名的一个程序
之后根据lpBaseAddress可以找到opcode的位置,大小是0xD6
解密只是一个简单的异或,可以写个脚本解析一下
123456789with open("./opcode_enc",'rb') as f: opcode = bytearray(f.read()) ...
2024CISCNGoReverse
0x00 前置来点GoCipher:https://pkg.go.dev/crypto/cipher
再来点Go的XXTEA:https://github.com/xxtea/xxtea-go/blob/master/xxtea/xxtea.go
0x01 解go语言和rust一样,静态是真看不明白
所以只能调试
然而这题里面有反调
根据调试时出现的字符串可以去搜索然后找到反调的地方
将jz改为jmp就可以过掉了
之后调试需要使用F4(运行至光标处),否则会跳到很多奇怪的地方
由于对go的反编译并不给力,因此大多时候还是以汇编为主
首先来到看上去像是真正执行的地方,可以看到有一个读文件的操作
在文件路径处下断点,往下跟
可以遇到第一个看起来像是加密的函数
进入这个main_tlFyZv,反编译后往下翻翻可以看到一个异或
在汇编看,可以发现基本没有别的操作了,合理怀疑这个函数就是一个异或
查看一下值,发现ptr内是一个表,这个表应该就是异或用的表了
先将其dump下来,然后写个脚本加密一下原flag,看看是否异或成功
12345678xortable = b"D7 ...
2024CISCNrust_baby
0x00 题目分析Rust,安全性极佳
静态代码基本没法看,只能动调了
0x01 解直接搜字符串,可以看到一段base64的字串:
跟进去解一下
可以看出来cryforhelp应该就是密文了
但是从哪里下手呢?毕竟Rust反编译是这样的
动调吧(
通过动调,一步步看我们的输入被进行了什么操作就行了
那么首先需要知道哪个函数是输入的
这个通过在输入时暂停然后往回跟就能找到这个位置了(此处改了一下名方便后面定位)
之后可以在下面找到输入被存储的地方
看一下整个循环
可以发现其将输入存入v27,如果输入为空的话则补69(ASCII == ‘E’),之后有一个函数,里面长这样
过于离谱,直接出去看v197
可以发现进行的操作比较简单,将一个八字节的字符串两两分组,之后分别-1,+0,+1,+2
然后v197做异或,输出到v23
之后在v23处下硬件断点,可以发现断在了这里
都看看会发现v93就是v23的内容,而v98是一个异或表,这一步是将上一步的结果与v98所存的异或表内的值进行异或
之后再跟v95
可以发现断在了这里,这是一个赋值,v101是上面v ...
DASCTFXGFCTF2024unwind
0x00 题目分析比较可惜这题没在规定时间内做出来,被劫持摆了一道
0x01 解无壳,直接上IDA
main函数相对比较简单,不难看懂,重点应该就是图中的sub_7A121C
跟进去可以发现是XXTEA算法,key就是byte_7AB048=[0x44, 0x41, 0x53, 0x21]
而sub_7AB000里面就是32字节长的东西
取一下enc
123456789101112131415161718import structdef read_int_array(file_name): with open(file_name, 'rb') as f: data = f.read() return struct.unpack('<'+'i' * (len(data) // 4), data)a = read_int_array('./enc.txt')enc = []for i in range(8): enc.append(a[i])for i in ...
DASCTFXGFCTF2024prese
0x00 题目分析跳跳虎,主要是要找到程序的执行路径,然后转换成能看的东西
0x01 解无壳,直接上IDA
超多if,上面还有超多while,实际上就是进行判断,如果条件满足,那么就不break,而是执行下面的程序
没什么技术含量,主要是一个个跳着看,IDA选中条件之后就会黄色高亮,一个个看就好了
这个main_crypto里面也是和main函数一样的跳
为了保护大脑不从头顶跳出去,我选择直接解释一下这个main_crypto
这玩意的重点在于标注出来的enc
它将进行一些位运算,然后将结果存入temp中,这个temp是一个密码表
将input数组中的值作为索引在密码表中找对应的值然后放回input内
相当于一个映射
加密过程我转为python了,可能比较好看一点(只是方便理解,不能运行的)
1234567len1 = 32i = 0input = []for i in range(256): enc = ~(len1 ^ i)for i in range(len1): input[i] = enc[input[i]]
解密就是逆运算,在main函数最下面可以找到这 ...
DASCTFXGFCTF2024ezVM
0x00 题目分析没啥好说的,就是VM,不过这个VM用的不是汇编,而是加减乘除,相当于整了个计算器出来
0x01 解无壳,两个附件,一个二进制的data和一个dll
直接上IDA
分成了两部分,一个是key,一个是flag
不过看得出来就算key输错了也是能继续输flag的
先看看key
由main函数可以知道,key有16位,而且全是数字(48<ASCII<57),然后两两一组丢进v11里面去了,sub_1400011E5里面有个scanf,应该是用于格式转换的
比较重要的就是sub_1400012D5了,返回值给了v9然后用v9进行判断
一直进去可以看到很经典的vm格式
直接写解释器吧
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001 ...
2023年春秋杯网络安全联赛冬季赛coos
0x00 题目分析VM,重点在于解释器,把opcode整出来
0x01 解无壳
直接拖IDA看看
main函数内容还算清晰,可以知道的信息是flag长度为32,下面的for循环应该是用于判断
sub_41103C跟进去可以发现有个scanf
sub_41145B将参数与0x66异或,测试了一下byte_41F5C4,应该只是用于解密输出
1234s = [0x01, 0x03, 0x12, 0x46, 0x12, 0x0e, 0x03, 0x46, 0x0A, 0x07, 0x01, 0x47, 0x66]for i in s: print(chr(i ^ 0x66), end="")# get the lag!
那么关键的函数就应该是sub_4112D0,sub_41128A和sub_41118B了
先跟进sub_41118B看看
给v9附了很多值,然后调了一个sub_4112DF
是VM,而且case不少
可以回收站了
先不碰这个了,回到main看看另外两个函数sub_4112D0和sub_41128A
先看看sub_4112D0,进去可以发现有很 ...
2023年春秋杯网络安全联赛冬季赛UPX2023
0x00 题目分析upx壳,但是有点小修改
主打一个爆破
0x01 解查壳,UPX,但不太一样
Don’t try : upx.exe -d
WHY?
CFF看看咋回事
大写变小写了(
丢010里面改大写就行
之后就能正常脱壳了
脱完直接上IDA
符号什么的都有,非常好看,不过要注意change函数和unk_46A020里的东西
先看看change函数
12v13 = 3v12 = std::string::length(a2)
第一个for循环初始化v9为3*len(a2),并全部用10进行填充
第二个for循环取a2中的值,然后放入v9中,v9被分为三段,每段长len(a2),a2的第一个值放入v9的第一段,第二个值放入第二段,第三个值放入第二段,第四个值放入第一段,第五个值放入第二段,第六个值放入第三段,之后以此类推,相当于做一个钟摆循环
第三个for将v9中不等于10的值按顺序放入a1中,最后返回一个a1
然后来看看unk_46A020里面的东西(转成dd了)
这个应该就是密文了
123char enc[] = { 0x09, 0x63, 0xD9, ...