0x00 信息内容安全实验报告
【实验目的】
了解格式化文件信息隐藏的特点,掌握如何利用HTML语言的特征来隐藏秘密信息,实现基于HTML语言的信息隐藏。
【实验环境】
(1) WindowsXP或 Vista 操作系统;
(2) Ultra Edit编辑工具;
(3) IE浏览器。
【原理简介】
HTML即超文本标记语言,是设计网页的基本语言。HTML语言由普通文本文件加上各种标记组成,没有图像、音频文件等所拥有的感觉冗余和多媒体数据冗余,在HTML语言中隐藏信息,要保持不可见性和抗攻击能力都很困难。目前商品化的HTML隐藏技术都是通过在HTML文件的回车换行符之前加入一些不可显示标记符号来实现。本实验中提出的HTML隐藏的方法主要是通过HTML语法特点来隐藏信息,常见方法有以下五种。
(1) 利用浏览器在解析HTML程序时会忽略掉行尾或HTML结束标记后的空白符号,不会影响浏览器的显示结果的特点来隐藏信息。在网页结束标记</HTML>后每行的行尾插入空格或Tab键隐藏信息,例如插入一个空格代表隐藏0,插入一个Tab代表隐藏1。
(2) 修改标记名称字符的大小写来隐藏信息。如用大写标记名称代表隐藏1,用小写标记名称代表隐藏0。这样,一个标记名称可隐藏1bit信息。
(3) 修改属性值字符串的大小写来隐藏信息。属性值字符串对大小写不敏感,如用属性字母的大写代表隐藏1,小写代表隐藏0。
(4) 用属性值用单引号、双引号或者不使用引号都可以表达相同含义的特点隐藏信息,如用双引号代表隐藏1,单引号代表隐藏0。
(5) 用单标记具有两种等价格式的特点来隐藏信息。如标记<BR>等价于<BR/>,可用<BR>代表隐藏1,<BR/>代表隐藏0。类似的标记还有<HR>=<HR/>,<IMG>=<IMG/>等。这样的一个标记可隐藏1bit信息。
本次实验笔者采用的是第一种方法,即在每行的行尾插入空格或Tab键隐藏信息。代码逻辑和结构与前面的实验 LSB 图像隐写基本一致。
0x01 Hide
如果用 ASCII 表示一个字母,隐写一个字母需要 7 或 8 个比特位。而用 1-26 表示一个字母,隐写一个字母仅需要 5 个比特位。鉴于 HTML 文件的行数一般不会太多,而该方法一行仅能隐写一个比特,所以笔者在这里摒弃了传统的 ASCII 表示方式,采用 1-26 的表示方式完成了对于大写字母的隐写。
def write_hide(i):
obj = open("hide.txt","a+",encoding="UTF-8")
obj.write(i + "\n")
obj.close()
def str2int(message):
string = ""
for i in message:
string = string + bin(ord(i) - 64).replace('0b','').zfill(5)
return string
def hide():
count = flag = 0
message = input('Please in put the message:')
string = str2int(message)
#print(string)
with open("html.txt","r",encoding="UTF-8") as f:
for i in f.readlines():
i = i.strip()
if count == len(string):
write_hide(i)
else:
if int(string[flag]) == 0:
i = i + " "
count = count + 1
flag = flag + 1
elif int(string[flag]) == 1:
i = i + "\t"
count = count + 1
flag = flag + 1
write_hide(i)
首先从网上随便copy一份html代码,自行填充或缩减代码至所需行数后保存为html.txt:
将脚本与html.txt置于同一目录下运行:
成功生成hide.txt:
0x02 Extract
def write_extract(i):
obj = open("extract.txt","a+",encoding="UTF-8")
obj.write(i)
obj.close()
def extract():
string = ""
count = 0
with open("hide.txt","r",encoding="UTF-8") as f:
for i in f.readlines():
if count == 5:
count = 0
string = chr(int(string,2) + 64)
write_extract(string)
string = ""
i = i.strip("\n")
if i[-1] == " ":
string = string + "0"
count = count + 1
if i[-1] == "\t":
string = string + "1"
count = count + 1
将脚本与hide.txt置于同一目录下运行:
成功生成extract.txt:
0X03 The_fu11_scr1pt
def write_hide(i):
obj = open("hide.txt","a+",encoding="UTF-8")
obj.write(i + "\n")
obj.close()
def write_extract(i):
obj = open("extract.txt","a+",encoding="UTF-8")
obj.write(i)
obj.close()
def str2int(message):
string = ""
for i in message:
string = string + bin(ord(i) - 64).replace('0b','').zfill(5)
return string
def hide():
count = flag = 0
message = input('Please in put the message:')
string = str2int(message)
#print(string)
with open("html.txt","r",encoding="UTF-8") as f:
for i in f.readlines():
i = i.strip()
if count == len(string):
write_hide(i)
else:
if int(string[flag]) == 0:
i = i + " "
count = count + 1
flag = flag + 1
elif int(string[flag]) == 1:
i = i + "\t"
count = count + 1
flag = flag + 1
write_hide(i)
def extract():
string = ""
count = 0
with open("hide.txt","r",encoding="UTF-8") as f:
for i in f.readlines():
if count == 5:
count = 0
string = chr(int(string,2) + 64)
write_extract(string)
string = ""
i = i.strip("\n")
if i[-1] == " ":
string = string + "0"
count = count + 1
if i[-1] == "\t":
string = string + "1"
count = count + 1
def main():
mode = input("Please input the mode:")
if mode == 'hide':
hide()
if mode == 'extract':
extract()
if __name__ == '__main__':
main()
0x04 Summary
将html.txt改为html.html,将hide.txt改为html.html,open两者进行比较:
证实该隐写方法不会影响浏览器的显示结果。
如果不对文件进行utf-8编码,则会导致html乱码: