Tarmful

Description
Just decompress them all.
https://raw.githubusercontent.com/hitcon2014ctf/ctf/master/tarmful-3f13b82f7794de783adfd6fa9928ad2c.zip
https://dl.dropbox.com/s/oh8cb6i63x7zggh/tarmful-3f13b82f7794de783adfd6fa9928ad2c.zip

写在前面的碎碎念

此题技术含量较低,考的只是一些基本功,不过分值竟然不算最低…… 作为全程给两位大神打辅助的人来说,这种题大神是看不上的……

解题思路

此题附件为一个zip压缩包,下载之。

粗看以为是一个循环压缩包(即压缩包里面套压缩包:1024.zip->1023.zip->1022.zip->….),心里一乐,辣么简单的题目就能赚辣么多分,好开森~~于是写了一个循环解压的python脚本,之后跑了一下,突然……T^T,发现后面有tar.gz之类的其他类型压缩包。

无奈,切换到linux下,操刀shell。思路还是和一开始一样,判断扩展名,之后根据类型解压即可。代码如下:

1
2
3
4
5
6
7
if [ "${filename##*.}" = "gz" ]; then
tar -zxf ${filename}
elif [ "${filename##*.}" = "bz2" ]; then
tar -jxf ${filename}
elif [ "${filename##*.}" = "Zip" ]; then
unzip ${filename}
fi

本以为这题就crack了,but……又有情况出现,出现了没有扩展名的压缩包(重度Windows用户真心依赖扩展名)。于是修改代码,利用file判断文件类型,再分类解压。

这样程序大致雏形完成,不过其中出现了很多畸形压缩包,由于竞赛时间有限,并没有写出一个完善的shell的策略,而是采用手工修改畸形压缩包的办法完成占比例不算太大的畸形压缩包(大概10几个吧)。

其中出现的畸形文件大致有这么几类:

  1. 普通畸形文件名
  2. 掺杂有shell脚本的畸形文件名,如:672; while true; do; done
  3. UTF-8编码的畸形文件名
  4. 连续嵌套的文件夹(解压后有产生有一定深度的文件夹,文件被放在最里面的文件夹中)
  5. 解压后文件夹与文件名同名情况(无法拷贝到同一层目录)
    6.解压后不只一个文件,还存在其他文件夹(同目录级别)
  6. 貌似还有一些,没仔细统计……
  7. 整个解题的shell脚本非常简单,但写的比较丑,就不给出了。

改进的解题脚本

不过采用“基本靠脚本,偶尔靠人手的办法”,虽然拿到了最终的flag,总有些不完美,这里给出后来修改过的shell,直接一键解到flag。

首先粗略介绍一下脚本原理:

  1. 对解压后获得的有效文件夹及有效文件(所谓有效文件即目标文件,而不是那些用来迷惑的文件夹或文件)改名,防止因为文件名问题(如重名,畸形文件名等)造成无法解压。
  2. 根据文件类型解压,并进入下一轮。

该脚本使用方法:

  1. 假设目前所在工作目录为/home/yyx/CTF
  2. 将脚本zip.sh放在CTF目录下
  3. 创建zip目录
  4. 在zip目录中创建f_1024
  5. 将下载回来的zip放入f_1024中并改名ff_1024
  6. cd到工作目录,并执行./zip.sh

初始工作目录如下:

1
2
3
4
5
/home/yyx/CTF
├── zip
│ └── f_1024
│ └── ff_1024
└── zip.sh

脚本如下:

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
#!/bin/bash
num=1024
rootpath='/home/yyx/CTF/zip'
folder="f_${num}"
filename="ff_${num}"
while [ $num -gt -1 ]; do
cd ${rootpath}/${folder}
#change file path
mv ${rootpath}/${folder}/${filename} ${rootpath}/${filename}
#get file type
filetype=$(file ${rootpath}/${filename} | awk '{print $2}')
#unpack file
cd ${rootpath}
if [ "${filetype}" = "gzip" ]; then
tar -zxf ${filename}
elif [ "${filetype}" = "bzip2" ]; then
tar -jxf ${filename}
elif [ "${filetype}" = "Zip" ]; then
unzip ${filename}
else
echo "sth new :("
break
fi
#delete old files & folders
rm ${rootpath}/${filename}
rm -rf ${rootpath}/${folder}
#update name of folder and file
num=$(( $num - 1 ))
folder="f_${num}"
filename="ff_${num}"
#change folder name
cd ${rootpath}
newfolder=$(ls -l ./ | grep ^d | awk '{print $9}')
mv "${rootpath}/${newfolder}" "${rootpath}/${folder}"
#get file name
cd ${rootpath}/${folder}
newfile=$(ls -l ./ | grep ^- | awk '{for(i=9;i<NF;i++) printf $i" "}{print $NF}')
#hack for nested folders
while [ "${newfile}" = "" ]; do
tmp="$(ls -l ./ | grep ^d | awk '{print $9}')"
cd $tmp
newfile=$(ls -l ./ | grep ^- | awk '{for(i=9;i<NF;i++) printf $i" "}{print $NF}')
done
#change file name
curr=$(pwd)
mv "${curr}/${newfile}" "${rootpath}/${folder}/${filename}"
done

最后拿到flag为HITCON{SO0O0OO_MaNy_7Ar_Le\/eLs}