0x00 题目分析

关于linux的file命令和magic file:https://blog.csdn.net/shenwansangz/article/details/50506507

对file命令的版本有要求

以当前题目为例,安装5.41版本的file命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
wget ftp://ftp.astron.com/pub/file/file-5.41.tar.gz

tar -xvzf file-5.41.tar.gz

cd file-5.41

./configure

make

sudo make install

# Output:
# 'file-5.41.tar.gz saved'
# 'file-5.41/ configured'
# 'file-5.41/ compiled'
# 'file-5.41/ installed'

0x01 解

随便在flag里面写点东西

然后使用

1
file -m flag.mgc -d flag

其中file -d用于输出调试信息

从输出可以看出一个比较

string,=flag{,””]

所以将flag文件的内容改为flag{

再次执行命令

又多了个比较

此处参考magic文件格式:https://blog.csdn.net/qq_35677314/article/details/120687202

leshort 小端字节序的两字节值

写个小脚本过一下这一段比较

1
2
3
4
5
6
7
8
9
10
11
import os

f = open('flag', 'w')
f.write('flag{' + '*' * (64 - len('flag{')))
f.close()

f = open('flag', 'ab')
f.write((0x76 ^ 111).to_bytes(2,'little'))
f.close()

print(os.popen("file -m flag.mgc -d flag").read())

看来比较还不少

整点自动化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import re
import subprocess

f = open('flag', 'w')
f.write('flag{' + '*' * (64 - len('flag{')))
f.close()

for i in range(2, 100):
# 运行命令并捕获输出
text = subprocess.run(['file', '-m', 'flag.mgc', '-d', 'flag'],
capture_output=True, text=True, check=True).stderr

# 使用正则筛选需要的数据
data = re.findall(f'{int(i)}: >* (\d+) leshort\^([\da-f]+),=(\d+),""]', text)
print(i, "data:", data)
f = open('flag', 'ab')

# 写入flag文件使用
f.write((int(data[0][1], 16) ^ int(data[0][2])).to_bytes(2, 'little'))
f.close()

运行到34报错

看看调试信息变成什么样了

看来脚本得改

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
import re
import subprocess

f = open('flag', 'w')
f.write('flag{' + '*' * (64 - len('flag{')))
f.close()

for i in range(2, 34):
# 运行命令并捕获输出
text = subprocess.run(['file', '-m', 'flag.mgc', '-d', 'flag'],
capture_output=True, text=True, check=True).stderr

# 使用正则筛选需要的数据
data = re.findall(f'{int(i)}: >* (\d+) leshort\^([\da-f]+),=(\d+),""]', text)
print(i, "offset:", data[0][0], "data:", data)
f = open('flag', 'ab')

# 写入flag文件使用
f.write((int(data[0][1], 16) ^ int(data[0][2])).to_bytes(2, 'little'))
f.close()


for i in range(34, 100):
# 运行命令并捕获输出
text = subprocess.run(['file', '-m', 'flag.mgc', '-d', 'flag'],
capture_output=True, text=True, check=True).stderr

# 使用正则筛选需要的数据
data = re.findall(f'{i}: >* \d+\(byte,&0\), byte\^([\da-f]+),=([-\d]+),""]', text)
off = re.findall(f'mget/128 @(\d+):', text)
print(i, "offset:", off[-1], "data:", data)
f = open('flag', 'rb+')
f.seek(int(off[-1]))

# 写入flag文件使用
f.write(((int(data[0][0], 16) ^ int(data[0][1])) & 0xff).to_bytes(1, 'little'))
f.close()

再次运行到报错

再看看输出的调试信息

看来就差临门一脚了

补一下花括号

1
# flag{_oh_yes_you_got_the_flag___^_^__}