十天的训练赛
1.Re1-100
IDA 查看主要逻辑
1 | responseTrue(); #flag正确 |
1 | strncmp(bufParentRead, "{daf29f59034938ae4efd53fc275d81053ed5be8c}", 0x2AuLL) |
经过变换后的 flag 和 {daf29f59034938ae4efd53fc275d81053ed5be8c}
对比
退回上一层的检查:
confuseKey(bufParentRead, 42)
可以看到是把一个字符串分割成了四段然后重组 3 4 1 2
1 | 原文:{daf29f5903 4938ae4efd 53fc275d81 053ed5be8c} |
往上看那几个判断
1 | strncmp(&bufParentRead[31], "4938ae4efd", 10uLL) |
31 到 41 位是 4938ae4efd
1 到 11 位是 53fc275d81
对得上flag就是 {53fc275d81053ed5be8c4938ae4efddaf29f5903}
2.APK-逆向2
这个东西是个 .net 文件 当时我傻傻的拿 IDA 去看,问了一下队友,用 dnSpy 逆
看到程序启动后会连接到本地的 31337 端口然后就把一个 CTF{ 开头的东西发给我们
我用的是 ncat 监听本地的 31337 端口
1 | ncat -kl 31337 |
打开文件得到flag
3.Shuffle
这个没什么好说的
4.key
IDA 打开发现是个 C++ 很多函数,一开始我是手逆,逆了几个,被劝退了
后面动态调试,在 sub_4020C0 函数(这个就是最终检查 flag 的函数)下断点
flag 就是 eax 中的 “idg_cni~bjbfi|gsxb”
5.zorropub
这个题我用了极其暴力的一种做法
这是一个 MD5
然后你输入一个大于等于 16 小于 0xFFF 的东西,后面验证通过就会给你 flag
我把服务挂到本机的 4444 端口
1 | ncat -vc zorro_bin -kl 4444 |
然后就是
6.babymips
给的是一个 mips 指令的 ELF
我是用 ghidra 逆
main 函数:
1 | scanf("%32s",ipt); |
这里的加密是把我们的输入和 0x20 - i 异或了一遍
这里要注意的是运算符的优先级
先是 - 然后才是 ^
然后把前五位和 _fdata( Q|j{g ) 进行对比
解出前五位
1 | enc = "Q|j{g" |
得到 :qctf{
分析flag后 27 位的加密 :
1 | while (flag_len = strlen(ipt), i < flag_len) { |
这个主要是交换了二进制位的位置
例如:字符的二进制位(数字代表位置不是立即数):
76543210
(i & 1) == 0
代表下标为偶数
((int)ipt[i] << 0x1a) >> 0x18) | ipt[i] >> 6;
先是 << 0x1a
相当于变成了:7654321000000000000000000000000000
再 >> 0x18
变成了 :7654321000
ipt[i] >> 6
得出:76
现在把第七第六位(76)|(7654321000)
变成了7654321076
下标为单数的同理
然后是最后一步的验证:
1 | iVar1 = strncmp(ipt + 5,enc,0x1b); |
enc可以在我截图的左栏看到
双击 enc 再双击 DAT_00400b98 就有
1 | DAT_00400b98 XREF[2]: encrypto:0040094c(*), |
1 | enc = 52 FD 16 A4 89 BD 92 80 13 41 54 A0 8D 45 18 81 DE FC 95 F0 16 79 1A 15 5B 75 1F 00 |
完整的脚本:
1 | enc = b'\x52\xFD\x16\xA4\x89\xBD\x92\x80\x13\x41\x54\xA0\x8D\x45\x18\x81\xDE\xFC\x95\xF0\x16\x79\x1A\x15\x5B\x75\x1F' |
7.secret-galaxy
这个运行了没啥输入的地方,看代码也看不出啥(我太菜了),就 OD 运行完了之后 搜字符串,得到 flag
8.serial
这个东西有花指令
写个脚本去花: