一、實驗目的
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工具進行文件傳輸,如下圖所示: