骑麦兜看落日

[WriteUp]网鼎杯

字数统计: 675阅读时长: 3 min
2018/08/21 Share

Reserve


advanced


题目信息

please keep identification in your pocket :)

Download 备用下载(mbo2)


解题过程

这是D语言写的程序,入口函数是_Dmain,开始傻傻的分析main里的d_run_main,太傻了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
__int64 Dmain()
{
__int64 v0; // rax
__int64 v1; // rax
__int64 v2; // rdx

v1 = D3src9hexencodeFAyaZQe(
*(_QWORD *)((char *)&D3src8enc_flagAya + v0),
*(_QWORD *)((char *)&D3src8enc_flagAya + v0 + 8));
D3std5stdio__T7writelnTAyaTQeZQqFNfQmQoZv(
v1,
v2,
69LL,
"welcome, here is your identification, please keep it in your pocket: ");
return 0LL;
}

这个函数的逻辑很简单,通过后边的hexencode函数得到一个字符串地址返回给v1,然后调用writeln函数打印

打印结果为

1
2
$ ./src
welcome, here is your identification, please keep it in your pocket: 4b404c4b5648725b445845734c735949405c414d5949725c45495a51

将其转化为字符串

1
2
3
4
5
6
7
str = '4b404c4b5648725b445845734c735949405c414d5949725c45495a51'
data = ''

for x in range(0, len(str),2):
data += chr(int(str[x:x+2], 16))

print(data)

得到结果

1
K@LKVHr[DXEsLsYI@\AMYIr\EIZQ

看到其他战队有人直接猜出来了

1
2
3
4
5
6
7
8
9
10
data = 'K@LKVHr[DXEsLsYI@\AMYIr\EIZQ'
flag = ''

for i in range(len(data)):
if(i%2==0):
flag += chr(ord(data[i])^45)
else:
flag += chr(ord(data[i])^44)

print(flag)

开始不太明白怎么猜出来的,后来想了想可能是因为flag的格式比较固定,直接异或试一下可能就猜出来了,get一个技能

不过刘锅不知道为什么会突发奇想,去搜了下函数名(可能也是一个套路吧,毕竟我做题太少了),找到一个_D3src7encryptFNaNfAyaZQe函数,这个函数有将近500个加密函数就不贴了,头没刘锅硬我也就不分析了

总之这个函数最后会得到一个返回值猜想就是flag了,把这个替换掉hexencode的位置再次运行得到flag

1
2
$ ./src
welcome, here is your identification, please keep it in your pocket: flag{d_with_a_template_phew}

解密算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
call_addr = 0x57D52
enc_addr = 0x566EC
asm = b'\xE8\x26\xFF\xFF\xFF'

def addr(src,dest):
endian = []
offset = dest - src

if offset < 0:
offset = 0xffffffff + offset + 1
for x in range(4):
endian.append(offset & 0xff)
offset >>= 0x8
return bytes(endian)

with open('src','rb') as f:
data = f.read()
offset = data.find(asm) + 1
addr = addr(call_addr, enc_addr)
data = data[0: offset] + addr + data[offset+4:]

with open('src','wb') as f:
f.write(data)

相关资料


Beijing


题目信息

Beijing, I’m coming.

Download 备用下载(jtn1)


解题过程

找到主函数发现不断调用了同一个函数,对该函数分析发现是一个异或函数,每次根据传入的不同值进行异或

按照出题人的意思,按照调用顺序找到被异或的值


解密算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
base_addr = 0x8000 + 0x1000
xor_addr = 0x8460 + 0x1000 - base_addr
key_begin = 0xA020 - base_addr
key_end = 0xA040 - base_addr
flag = ''

with open('beijing','rb') as f:
data = f.read()
key = data[key_begin:key_end]

for i in range(len(data)):
if data[i] == 0xE8 and ((data[i+2]<<8) + data[i+1]) == 0xffff + xor_addr-i-5 + 1:
offset = i - 10 + data[i-10:i].find(b'\x04\x08') - 2
addr = (data[offset+1]<<8) + data[offset] - base_addr
flag += chr(key[data[addr]*2]) if data[addr] < len(key) else chr(key[0])

print(flag)
CATALOG
  1. 1. Reserve
    1. 1.1. advanced
      1. 1.1.1. 题目信息
      2. 1.1.2. 解题过程
      3. 1.1.3. 解密算法
      4. 1.1.4. 相关资料
    2. 1.2. Beijing
      1. 1.2.1. 题目信息
      2. 1.2.2. 解题过程
      3. 1.2.3. 解密算法