Oops-re's Blog.

NCTF--复现

字数统计: 656阅读时长: 3 min
2022/12/06

NCTF复现

虽然比了两天,但是一题也没有做出来

菜。。

REVERSE

ez_rev

Z3爆破,由于对z3的不了解导致没有解出来QAQ

(就是把Slover()放错位置辣)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
from z3 import *

checkstr=[0x7A, 0x08, 0x2E, 0xBA, 0xAD, 0xAF, 0x82, 0x8C, 0xEF, 0xD8,
0x0D, 0xF8, 0x99, 0xEB, 0x2A, 0x16, 0x05, 0x43, 0x9F, 0xC8,
0x6D, 0x0A, 0x7F, 0xBE, 0x76, 0x64, 0x2F, 0xA9, 0xAC, 0xF2,
0xC9, 0x47, 0x75, 0x75, 0xB5, 0x33]
def func(src,key):
des=[]
v3=key[3]
v4=src[3]
v5=key[0]
v6=src[0]
v7=src[1]
v8=key[1]
v9=src[2]
v10 = (v6+v4)*(key[0]+v3)
v11=key[2]
v12=v3*(v6+v7)
v13=(v3+v11)*(v7-v4)
v14=v4 *(v11-v5)
v15=v5 * (v9+v4)
des.append(v14+v10+v13-v12)
des.append(v15+v14)
des.append(v6*(v8-v3)+v12)
des.append(v6*(v8-v3)+(v8+v5)*(v9-v6)+v10-v15)
return des

key=[0x7E, 0x1F, 0x19, 0x75]


flag =""
for i in range(9):
s=Solver()
src=[BitVec("flag%i"%i,8) for i in range(4)]
v3=key[3]
v4=src[3]
v5=key[0]
v6=src[0]
v7=src[1]
v8=key[1]
v9=src[2]
v10 = (v6+v4)*(key[0]+v3)
v11=key[2]
v12=v3*(v6+v7)
v13=(v3+v11)*(v7-v4)
v14=v4 *(v11-v5)
v15=v5 * (v9+v4)
s.add(checkstr[i*4]==v14+v10+v13-v12)
s.add(checkstr[i*4+1]==v6*(v8-v3)+v12)
s.add(checkstr[i*4+2]==v15+v14)
s.add(checkstr[i*4+3]==v6*(v8-v3)+(v8+v5)*(v9-v6)+v10-v15)
if s.check() == sat:
m=s.model()
flag += "".join([chr(m.eval(j).as_long()) for j in src])
print(flag)

just_run_it

简而言之,就是SM4加密

但是

看好像是IDA版本问题,IDA分析不是很准确,进而转汇编分析,还好不是很复杂

额。。。IDA顺手清数据了,没保存。。

主要就是先输入16字节的keyimage-20221206202233732

然后调用函数sub_407880key进行位置打乱

(这里可以通过输入0~0xf得到对应的打乱顺序)

image-20221206202609114

然后就是将打乱后的key和另一个数组进行按位异或

之后又进行一次位置的打乱

然后就是key的check

image-20221206202752613

得到最后的unk_428140加密后的key

写脚本拿到key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include<iostream>
using namespace std;
void func_1(char Rk[],char key[]){
Rk[0x0]=key[0];
Rk[0x1]=key[1];
Rk[0x5]=key[2];
Rk[0x6]=key[3];
Rk[0x2]=key[4];
Rk[0x4]=key[5];
Rk[0x7]=key[6];
Rk[0xc]=key[7];
Rk[0x3]=key[8];
Rk[0x8]=key[9];
Rk[0xb]=key[10];
Rk[0xd]=key[11];
Rk[0x9]=key[12];
Rk[0xa]=key[13];
Rk[0xe]=key[14];
Rk[0xf]=key[15];

}
int main(){
char key[] =
{
0x11, 0x4D, 0x92, 0xDA, 0xAC, 0x0B, 0x62, 0xF7, 0x54, 0x51,
0x27, 0x5A, 0x72, 0x62, 0x7B, 0x76
};
char xor_code[] =
{
0x46, 0x7C, 0xC1, 0x31, 0x67, 0xA2, 0xB4, 0x0D, 0x32, 0x11,
0x50, 0x15, 0x83, 0x3C, 0x14, 0x57
};
char buf[16];
func_1(buf,key);
for(int i=0;i<16;i++){
buf[i]^=xor_code[i];
}
func_1(key,buf);
for(int i=0;i<16;i++){
printf("%c",key[i]);
}

}

这里主要是从sub_41D188函数看到了SM4常量

image-20221206203402216

然后拿着key和密文去解密

image-20221206203545894

拿到flag

NCTF{b23a271e-2b15-4bb5-9719-738cffb83919}

CATALOG
  1. 1. NCTF复现
    1. 1.1. REVERSE
      1. 1.1.1. ez_rev
      2. 1.1.2. just_run_it