目的:
生成一个NTFS文件系统,要求:
1、$MFT至少2个碎片
2、根目录下建90个以从1开始的数字编号为名的子目录,每个子目录下建80-100个文件,文件编号从1开始编起。
3、有大量文件是由2个或以上碎片组成。(本例多为2个碎片)
1、shell 脚本如下:
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
57
58
59
60
61
62
|
! /bin/sh
# Script.sh # # # Created by 张宇 on 2017/3/29. 此脚本已包含后面的命令 # mkdir ~/$1
cd ~/$1
qemu-img create -f raw $1.img 1G qemu-nbd -f raw -c /dev/nbd0 $1.img
parted -s /dev/nbd0 mklabel msdos
parted -s /dev/nbd0 mkpart -s primary NTFS 128s 100%
mkfs.ntfs -f /dev/nbd0p1
mount .ntfs-3g /dev/nbd0p1 /mnt
#第一段for,先创建30个子目录,每个目录下80-100个文件,大小为16K-48K,这一段基本连续 for ((i=1;i<=3;i++)); do
mkdir /mnt/ $i
r1=$(($RANDOM % 20))
for ((ii=1;ii<80+$r1;ii++)); do
r2=$(($RANDOM % 64 + 32))
dd if = /dev/urandom of= /mnt/ $i/$ii bs=512 count=$r2
done
done #sleep 60 便于让文件系统flush #sleep 60 mkdir /mnt/padding
cd /mnt/padding
#填充65000个文件,这样可以使NTFS $MFT填充到第一个使用的数据区段,从而产生$MFT 碎片。 for ((i=1;i<65000;i++)); do
touch $i
done #创建出其他4-90子目录,这些文件会位于$MFT的第二个片断或以后 for ((i=4;i<=90;i++)); do
mkdir /mnt/ $i
r1=$(($RANDOM % 20))
for ((ii=1;ii<80+$r1;ii++)); do
r2=$(($RANDOM % 64 + 32))
dd if = /dev/urandom of= /mnt/ $i/$ii bs=512 count=$r2
done
done #sleep 60 #第二段for,使用dd把第一段for创建出的文件,从0-16K的位置,写入48K-80K,基本保证>约2个碎片,子目录3下的文件是第一段$MFT下的文件,3之后的为$MFT第二个片断。 for ((i=3;i<=90;i++)); do
cd /mnt/ $i
for ii in ` ls `; do
r2=$(($RANDOM % 64 + 96))
r3=$(($RANDOM % 32))
dd if = /dev/urandom of= /mnt/ $i/$ii bs=512 seek=$r3 count=$r2
done
done #删除padding,以免目录结构太臃肿 rm -rf /mnt/padding
cd /mnt
find . - type f -print| xargs md5sum -b | tr a-z A-Z 1>~/$1 /md5 .list
for i in ` find . - type f`; do ntfscluster -f -F $i /dev/nbd0p1 ; done 1>~/$1 /file .info 2> /dev/null
|
2、在shell中执行如下命令:
1
2
3
4
5
6
|
qemu-img create -f raw test2.img 1G qemu-nbd -f raw -c /dev/nbd0 test2.img
fdisk /dev/nbd0 #此命令交互,目的为/dev/nbd0分个区,不想交互,可使用parted加参数
mkfs.ntfs -f /dev/nbd0p1
mount .ntfs-3g /dev/nbd0p1 /mnt
/bin/bash run.sh
|
3、测试结果是否满意:
命令一:ntfscluster -f -I 0 /dev/nbd0p1
结果与预想相符,$mft果然为2个片断:
Forced to continue.
Dump: /$MFT
0x10 - resident
0x30 - resident
0x80 - non-resident
VCN LCN Length
0 4 16387
16387 20488 1880
0xb0 - non-resident
VCN LCN Length
0 2 2
2 16391 1
命令二:ntfscluster -f -F 1/ /dev/nbd0p1
结果与预想相符,抽样目录,也为2个片断
Forced to continue.
Unnormalized path 1/
Dump: /1
0x10 - resident
0x30 - resident
0x50 - resident
0x90 - resident
0xa0 - non-resident
VCN LCN Length
0 53328 2
2 49238 1
0xb0 - resident
命令三: ntfscluster -f -F 60/9 /dev/nbd0p1
结果与预想相符,抽样文件,也为2个片断
Forced to continue.
Dump: /60/9
0x10 - resident
0x30 - resident
0x50 - resident
0x80 - non-resident
VCN LCN Length
0 211991 8
8 115298 7
4、生成所有文件的md5 哈希,便于生成考核答案
1
2
|
cd /mnt
find . - type f -print| xargs md5sum -b | tr a-z A-Z
|
5、生成所有文件的碎片信息,便于生成考核答案
1
2
|
cd /mnt
for i in ` find . - type f`; do ntfscluster -f -F $i /dev/nbd0p1 ; done 2> /dev/null
|
6、生成目录的碎片信息,便于生成考核答案
1
2
|
cd /mnt
for i in ` find . - type d`; do ntfscluster -f -F $i /dev/nbd0p1 ; done 2> /dev/null
|
7、生成元文件的文件记录信息,便于生成考核答案
1
|
for ((i=0;i<16;i++)); do ntfscluster -f -I $i /dev/nbd0p1 ; done 2> /dev/null
|
或者通过命令:ntfscluster -i -f /dev/nbd0p1,
查看如下值:initialized mft records : 73115
再执行,下面命令即可将所有文件的碎片信息打印出来,再做加工,即可生成考核答案
1
|
for ((i=0;i<73115;i++)); do ntfscluster -f -I $i /dev/nbd0p1 ; done 2> /dev/null
|
ntfs-3g源码改动:
1、ntfscluster.c 400行while改为如下,目的是便于输出结果用grep,sed或awk加工
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
|
while ((rec = find_attribute(AT_UNUSED, ctx))) {
ntfs_log_info( " 0x%02x - " , ( int )le32_to_cpu(rec->type));
if (rec->non_resident) {
ntfs_log_info( "non-resident\n" );
runs = ntfs_mapping_pairs_decompress(vol, rec, NULL);
if (runs) {
ntfs_log_info( " INODE ATTR RUN# VCN LCN Length\n" );
for (i = 0; runs[i].length > 0; i++) {
ntfs_log_info( " %8lld 0x%02x %8lld %8lld %8lld %8lld\n" ,
( long long )(ino->mft_no & 0x0000FFFFFFFFFFFFUL),
( int )le32_to_cpu(rec->type),
( long long )i,
( long long )runs[i].vcn,
( long long )runs[i].lcn,
( long long )
runs[i].length);
}
ntfs_log_info( " [INFO]:0x%02xRuns:%d,Inode:%lld,path:%s\n" ,
( int )le32_to_cpu(rec->type),
i,
( long long )(ino->mft_no & 0x0000FFFFFFFFFFFFUL),
buffer);
free (runs);
}
} else {
ntfs_log_info( "resident\n" );
}
}
|
结果将如下:
Dump: /50/3
0x10 - resident
0x30 - resident
0x50 - resident
0x80 - non-resident
INODE ATTR RUN# VCN LCN Length
69425 0x80 0 0 194588 9
69425 0x80 1 9 217183 8
[INFO]:0x80Runs:2,Inode:69425,path:/50/3
考题及答案生成部分:
1、$MFT:$DATA
2、$MFT:$BITMAP
3、在$MFT第一个片断中的,拥有$DATA:RUNLIST唯一一条记录的文件,回答其MD5
4、在$MFT第二个片断中的,拥有$DATA:RUNLIST两条记录的文件,回答其MD5
5、读取某个拥有至少2个A0属性的目录块的MD5
6、给定一个起始簇号,解释一个RUNLIST的前3条记录(样本中至少有3条记录)
7、恢复一个删除的文件 (可生成答案后,删除某个目录,再恢复其下面的某个文件即可)