一、实验目的
1. 熟悉安胜安全操作系统的运行环境
2. 熟悉隐蔽通道的工作原理
二、实验内容
1.完成发送和接收程序的编写、编译和执行
2.演示存在的隐蔽通道场景:
三、实验过程、结果
(1)测试准备
1. 启动到隐蔽通道处理前的安全核SecLinux
2. 创建两个用户user_h和user_l,user_h的安全范畴包含user_l的安全范畴,user_h的安全级高于user_l的安全级。此外,设置用户主目录安全级与用户安全级相同;将两个用户主目录自主访问控制权限放开,即均通过chmod命令将其权限设为0777,允许u,g,o可读、写和执行。
3. 检验SecLinux的安全性:
高级用户可以读低安全级文件,但是不能创建低安全级文件,也不能通过拷贝等方式向下传递信息。低级用户无法读高安全级文件。
(2)选用的隐蔽通道:最近访问时间信道
信道名称:
最近访问时间信道
信道类型:
常驻内存型
中介变量:
数据结构stat的st_atime成员
存在条件:
当用户进程访问一个文件时,系统内核都会更新该文件的最近访问时间。同时,系统的安全策略允许高安全级用户读访问低安全级的文件,而低安全级的可以察觉这种访问。
发送方动作:
发送方读取机密文件,然后,根据该文件内容的当前字节的ASIIC码决定要访问的低级用户的文件数目。
接受方动作:
首先确定一组高级用户可以读的文件。使用系统调用stat读取这些文件的最近访问时间信息,作为原始信息记录下来。待高级用户发送完消息后,使用系统调用stat读取这些文件的最近访问时间信息,并与原始信息比较,将最近访问事件有变化的时间记录目录解释为ASIIC码值。
噪音情况:
出现噪音的原因主要是接收方在接收的CPU时间片可能会不够用。
带宽估计:
不小于30比特/秒。
处理措施:
主要依靠审计方法。
标记变量:
CC_AT
(3)同步机制
采用sleep(秒)/usleep(微秒)制造同步。
当一个进程sleep时,就将cpu的控制权交给其他进程,直到sleep时间已到,重新获得cpu的控制权。
这种同步技术容易实现,适于演示。
但是由于进程发送不同字符所用时间不同,而sleep时间一旦指定就是固定的,不能在程序运行期间更改,因此这种同步必然造成时间浪费。
(4)实验结果
如下图所示,左侧是发送端at_sender,右侧是接收端at_receiver,发送端从同目录的sender_text.txt文件获取发送数据,通过隐蔽通道发送到接收端,接收端接到数据后保存到同目录的receiver_text.txt文件中,发送端文件中存放的数据是abcdefg。
从下图可以看到receiver_text.txt的内容,可以看出,7个字符abcdefg都正确传输。
(5)发送端源代码
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
void accessFiles(int count);
void sendChar(char ch);
int main()
{
char ch;
FILE *fp;
if ((fp = fopen("./sender_text.txt", "r")) == NULL) //打开要发送的文件
{
printf("fopen error.\n");
exit(0);
}
while ((ch = fgetc(fp)) != EOF)
{
sendChar(ch); //每隔2秒发送每一个字符ch
sleep(2);
}
accessFiles(128); //将所有文件访问时间同步,作为结束发送的标识
fclose(fp);
return 0;
}
void accessFiles(int count)
{
FILE *fp;
char name_tag[25];
char tmp;
int i;
for (i = 0; i < count; i++) //读取前count个文件,从而修改其访问时间
{
sprintf(name_tag, "./tmp/%d.txt", i);
if ((fp = fopen(name_tag, "r")) == NULL)
{
printf("fopen error.\n");
exit(0);
}
tmp = fgetc(fp);
fclose(fp);
}
}
void sendChar(char ch) //字符发送函数,通过创建ch个进程表示发送字符ch,这些进程持续2秒
{
printf("Sending char: [%c].\n", ch);
accessFiles((int) ch);
}
(6)接收端源代码
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
int bStart = 0;
void createFiles();
char checkFiles();
char receiveChar();
void writeToFile(char ch);
int main()
{
char ch;
remove("./receiver_text.txt"); //先删除之前接受的文件
createFiles(); //创建中间文件
while (((ch = receiveChar()) != (char) 0) || bStart == 0)
{ //每隔2秒接受一次字符
if (bStart == 0)
{
printf("Not start.\n"); //bStart为0表示发送端还没开始发送
}
else
{
printf("Write [%c] to file.\n", ch); //接收到发送端发送字符ch
writeToFile(ch); //将ch写入接收文件
}
}
printf("End.\n");
return 0;
}
void createFiles()
{
FILE *fp;
char name_tag[25];
int i;
for (i = 0; i < 128; i++) //由于ASCII码有128个字符,因此这里创建128个文件
{
sprintf(name_tag, "./tmp/%d.txt", i);
if ((fp = fopen(name_tag, "w+")) == NULL)
{
printf("fopen error.\n");
exit(0);
}
fputc('t', fp); //文件内容为"test"
fputc('e', fp);
fputc('s', fp);
fputc('t', fp);
fclose(fp);
}
}
char checkFiles() {
struct stat buf;
int result;
int old_time_int = -1;
int time_int;
char name_tag[25];
char ch;
int i;
for (i = 0; i < 128; i++)
{
sprintf(name_tag, "./tmp/%d.txt", i);
result = stat(name_tag, &buf); //获取文件信息到buf中
if (result != 0)
{
printf("checkFiles error.\n");
}
else
{
time_int = buf.st_atime; //获取文件的访问时间
//printf("File: [%s], Access time: [%d].\n", name_tag, time_int);
if (old_time_int != -1 && old_time_int - time_int > 1) //当前后文件的访问时间相差大于1秒时,之前的文件就是发送方访问过的文件
{
ch = (char) i;
printf("File: [%s], access time: [%d], previous file acces time: [%d].\n", name_tag, time_int, old_time_int);
printf("Updated file: [%d], Receiving char: [%c].\n", i, ch);
bStart = 1; //这时发送已经开始,等待触发发送结束标志
return ch;
}
old_time_int = time_int;
}
}
return 0;
}
char receiveChar()
{
sleep(2); //每隔2秒接收一次字符
return checkFiles();
}
void writeToFile(char ch) //将ch写入接收文件
{
FILE *fp;
if ((fp = fopen("./receiver_text.txt", "a")) == NULL)
{
printf("fopen error.\n");
exit(0);
}
fputc(ch, fp);
fclose(fp);
}
四、实验总结
实验收获:
学到了很多隐蔽通道方面的知识,也进一步熟悉了安胜操作系统的命令用法。
总结实验过程中遇到的问题及解决方法:
在linux中开发C语言程序没有好用的IDE,编程非常不便。
解决方案:
在linux中用samba共享,将linux中的C语言代码共享在Windows下,这样可以在Windows下用Visual Studio等专业IDE对源代码进行编辑,保证了编码工作的高效进行。在编码完成后,用linux的scp工具进行文件传输,如下图所示: