这个程序的控制流好像有点奇怪
这题采用了一种奇妙的干扰技巧: 在函数序言的前面插入一块代码 该代码再通过改变返回地址来改变调用链
可以通过识别 push ebp 来确定真实的函数的位置
编辑这些函数 设置函数起始处跳过这些插入的代码块并勾选 BP-Based Frame 可以成功 F5
func1: func2: func3: func4 是纯粹的比较 func5: 其中 loc_4015AF 指向 func2 的第 13 行之后
main 函数中最后一段
每个小函数上下断点 找到执行的顺序如下
main -> func3 -> func5 -> func2 (后半段) -> func1 -> func4
最终总结出加密算法如下:
而解密是平凡的
DASCTF{TWpnemRuSTRkVzVsWVhOMmJqZzNOREoy}
null
基于 OATPP 框架的 HTTP 服务器
根据官网的 example 可以知道每个 Controller 都是一个 C++ 类
那么先找 Controller 类的虚表 可以通过字符串名称定位
寻找交叉引用两次
检查函数位于 CheckHandler.sub_40617E
开头这一段是通过反转比特解密字符串 简单修补了一下
第 52 行后也修补了一下(加了一个 string 的类型) 这里是在将 string 转化成 4*10 的 int 矩阵
第 101 行之后就是在做矩阵相乘
综合以上可以猜测 过关需要向其发送一个 GET 请求 abcdef=$FLAG 内部算法是解矩阵方程 XQ=P
DASCTF{CI5ZCM5piv5aaC5L2V5pS26LS555qE5Y}
小王是你的好朋友 最近他们公司下发了一个程序进行逆向竞赛 此程序会和公司内网的某个服务器建立TCP连接 小王需要你帮他找到PASSWORD 此外,小王已经发现,PASSWORD并不在服务器进行判断 由于你无法访问公司内网,小王贴心地给你抓了网络包(1.pcapng)并把程序给你(c)
远程过程调用的样本
先看全局变量 有一个 48 只的全局变量被一个函数改过 前 32 只是 4 个 int64 的数组 后 16 只是单字节串 都初始化为随机数
main 函数首先从服务器接收一个 32 只的串 传入一个以该串和刚才的随机数为参数的函数 sub_2090 然后把长度为 96 的输出再送回服务器 感觉非常有可能是在和服务器密钥交换
sub_2090 -> sub_1f9c -> sub_1e6e 一层一层点进去可以看到这样的函数
显然这是 128 位带模乘法
sub_1f9c 有和它类似的结构 为 128 位快速幂
再往前推断可知 func1 就是块大小为 8 的 RSA 分块加密 密钥是 32 位字串 前 16 位是 n 后 16 位是 e
然而 128 位的 n 并不大 直接放到 factordb 解密
p=1152921504606848051 q=2152921504606847269
总结密钥交换: 服务器生成 128 位的 n 和 e 发送给客户端 客户端生成 48 字节的密钥(暂时未知加密算法)用 e 加密送给服务器
继续看 main 函数 密钥交换过后它从服务器再拿 12 字节并通过 sub_1d9a 显然这是在解密服务器的数据 不然也就不用交换密钥了
其中 sub_1c0a 是块长度 64 的 TEA 解密
因此解密算法如下: 如果 buffer 长度小于16字节 对它使用 OTP 否则 对 buffer[len-16:len] buffer[len-17:len-1] ... buffer[0:16] 运行 TEA 解密
OTP 的密钥为 48 字串的后 16 字节 TEA 的 4 个密钥为前 32 字节
继续分析接收的 12 字节数据
main 函数将其分为 3 个整数 第一个整数为 RPC 调用号 后两个整数为参数
功能如下:
其中每段长度为 400
因此我们只需要模拟 CLNT 的动作把 memory 转储下来分析即可
SRV says: Hello, this is the remote server.
CLNT does: read from SRV to segment 1 CLNT does: read from SRV to segment 2 SRV says: Please enter your password
CLNT does: read from stdin to segment 0 CLNT does: read from SRV to segment 8 CLNT does: read from SRV to segment 4 CLNT does: read from SRV to segment 5 CLNT does: read from SRV to segment 6 CLNT does: read from SRV to segment 7 CLNT does: exec code at segment 8 CLNT does: print segment 3 CLNT quit
真的是很平凡的加密
DASCTF{5rOV562J5Y5pu+5amn6Zuv2B5aSa5Liq}
你说的这个好朋友,是不是你自己?
23年7月23日于杨舍
s
=
[
3279
,
3264
,
3324
,
3288
,
3363
,
3345
,
3528
,
3453
,
3498
,
3627
,
3708
,
3675
,
3753
,
3786
,
3930
,
3930
,
4017
,
4173
,
4245
,
4476
,
4989
,
4851
,
5166
,
5148
,
4659
,
4743
,
4596
,
5976
,
5217
,
4650
,
6018
,
6135
,
6417
,
6477
,
6672
,
6891
,
7056
,
7398
,
7650
,
7890
]
for
i
in
range
(
10
,
30
,
2
):
s[i
+
1
],s[i]
=
s[i],s[i
+
1
]
for
i
in
range
(
40
):
assert
(s[i]
%
3
=
=
0
)
s[i]
/
/
=
3
for
i
in
range
(
40
):
s[i]
+
=
i
for
i
in
range
(
20
):
s[
10
+
i]^
=
i
*
(i
+
1
)
for
i
in
range
(
40
):
s[i]
-
=
i
*
i
for
i
in
range
(
40
):
s[i]^
=
0x401
flag
=
''.join(
chr
(b)
for
b
in
s)
print
(flag)
s
=
[
3279
,
3264
,
3324
,
3288
,
3363
,
3345
,
3528
,
3453
,
3498
,
3627
,
3708
,
3675
,
3753
,
3786
,
3930
,
3930
,
4017
,
4173
,
4245
,
4476
,
4989
,
4851
,
5166
,
5148
,
4659
,
4743
,
4596
,
5976
,
5217
,
4650
,
6018
,
6135
,
6417
,
6477
,
6672
,
6891
,
7056
,
7398
,
7650
,
7890
]
for
i
in
range
(
10
,
30
,
2
):
s[i
+
1
],s[i]
=
s[i],s[i
+
1
]
for
i
in
range
(
40
):
assert
(s[i]
%
3
=
=
0
)
s[i]
/
/
=
3
for
i
in
range
(
40
):
s[i]
+
=
i
for
i
in
range
(
20
):
s[
10
+
i]^
=
i
*
(i
+
1
)
for
i
in
range
(
40
):
s[i]
-
=
i
*
i
for
i
in
range
(
40
):
s[i]^
=
0x401
flag
=
''.join(
chr
(b)
for
b
in
s)
print
(flag)
*(_DWORD *)_abcdef = 0x9B9C9D9E;
*(_WORD *)&_abcdef[4] = 0x999A;
_abcdef[6] = 0;
bitwise_neg(_abcdef, 6);
*(_QWORD *)_403 = 0xDFCCCFCBC1CE97C3LL;
*(_QWORD *)&_403[8] = 0x9A9B9B969D8D90B9LL;
*(_DWORD *)&_403[16] = 0x97D0C391;
*(_WORD *)&_403[20] = 0xC1CE;
_403[22] = 0;
bitwise_neg(_403, 22);
*(_QWORD *)_Wrong_flag = 0x9399DF9891908DA8LL;
*(_WORD *)&_Wrong_flag[8] = 0x989E;
_Wrong_flag[10] = 0;
bitwise_neg(_Wrong_flag, 10);
*(_DWORD *)_abcdef = 0x9B9C9D9E;
*(_WORD *)&_abcdef[4] = 0x999A;
_abcdef[6] = 0;
bitwise_neg(_abcdef, 6);
*(_QWORD *)_403 = 0xDFCCCFCBC1CE97C3LL;
*(_QWORD *)&_403[8] = 0x9A9B9B969D8D90B9LL;
*(_DWORD *)&_403[16] = 0x97D0C391;
*(_WORD *)&_403[20] = 0xC1CE;
_403[22] = 0;
bitwise_neg(_403, 22);
*(_QWORD *)_Wrong_flag = 0x9399DF9891908DA8LL;
*(_WORD *)&_Wrong_flag[8] = 0x989E;
_Wrong_flag[10] = 0;
bitwise_neg(_Wrong_flag, 10);
from
sage.
all
import
matrix,ZZ
P
=
matrix(ZZ, [
[
33211
,
36113
,
28786
,
44634
,
30174
,
39163
,
34923
,
44333
,
33574
,
23555
],
[
35015
,
42724
,
34160
,
49166
,
35770
,
45984
,
39754
,
51672
,
38323
,
27511
],
[
31334
,
34214
,
28014
,
41090
,
29258
,
37905
,
33777
,
39812
,
29442
,
22225
],
[
30853
,
35330
,
30393
,
41247
,
30439
,
39434
,
31587
,
46815
,
35205
,
20689
]
])
Q
=
matrix(ZZ, [
[
23
,
13
,
4
,
48
,
41
,
41
,
42
,
33
,
30
,
3
],
[
69
,
1
,
13
,
45
,
41
,
64
,
8
,
80
,
15
,
42
],
[
56
,
19
,
62
,
70
,
23
,
63
,
30
,
68
,
17
,
56
],
[
92
,
12
,
16
,
64
,
31
,
3
,
17
,
71
,
58
,
9
],
[
64
,
83
,
71
,
52
,
99
,
89
,
76
,
68
,
1
,
99
],
[
16
,
16
,
52
,
43
,
0
,
44
,
50
,
32
,
50
,
31
],
[
20
,
63
,
2
,
99
,
0
,
57
,
79
,
43
,
71
,
19
],
[
80
,
92
,
93
,
58
,
84
,
74
,
81
,
45
,
55
,
21
],
[
1
,
99
,
30
,
28
,
56
,
1
,
12
,
77
,
92
,
4
],
[
37
,
67
,
60
,
54
,
51
,
79
,
38
,
87
,
48
,
16
]
])
X
=
Q.solve_left(P)
flag
=
''
for
r
in
X:
for
c
in
r:
flag
+
=
chr
(c)
print
(flag)
from
sage.
all
import
matrix,ZZ
P
=
matrix(ZZ, [
[
33211
,
36113
,
28786
,
44634
,
30174
,
39163
,
34923
,
44333
,
33574
,
23555
],
[
35015
,
42724
,
34160
,
49166
,
35770
,
45984
,
39754
,
51672
,
38323
,
27511
],
[
31334
,
34214
,
28014
,
41090
,
29258
,
37905
,
33777
,
39812
,
29442
,
22225
],
[
30853
,
35330
,
30393
,
41247
,
30439
,
39434
,
31587
,
46815
,
35205
,
20689
]
])
Q
=
matrix(ZZ, [
[
23
,
13
,
4
,
48
,
41
,
41
,
42
,
33
,
30
,
3
],
[
69
,
1
,
13
,
45
,
41
,
64
,
8
,
80
,
15
,
42
],
[
56
,
19
,
62
,
70
,
23
,
63
,
30
,
68
,
17
,
56
],
[
92
,
12
,
16
,
64
,
31
,
3
,
17
,
71
,
58
,
9
],
[
64
,
83
,
71
,
52
,
99
,
89
,
76
,
68
,
1
,
99
],
[
16
,
16
,
52
,
43
,
0
,
44
,
50
,
32
,
50
,
31
],
[
20
,
63
,
2
,
99
,
0
,
57
,
79
,
43
,
71
,
19
],
[
80
,
92
,
93
,
58
,
84
,
74
,
81
,
45
,
55
,
21
],
[
1
,
99
,
30
,
28
,
56
,
1
,
12
,
77
,
92
,
4
],
[
37
,
67
,
60
,
54
,
51
,
79
,
38
,
87
,
48
,
16
]
])
X
=
Q.solve_left(P)
flag
=
''
for
r
in
X:
for
c
in
r:
flag
+
=
chr
(c)
print
(flag)
__int128 x = a;
__int128 y = 0;
while
(b != 0) {
if
(b & 1)
y = __modti3(x + y, m);
else
x = __modti3(2 * x, m);
b >>= 1;
}
return
y
__int128 x = a;
__int128 y = 0;
while
(b != 0) {
if
(b & 1)
y = __modti3(x + y, m);
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2025-3-14 01:49
被狗敦子编辑
,原因: 增加了图片,优化了语言
上传的附件: