OSS实验 隐蔽通道场景演示

花了两天时间,搞定了OSS课程的一个实验。由于对linux环境不熟悉,所以被vi,gcc折腾的够呛..
实验的要求是选择一个已经标识的隐蔽通道,通过在SecLinux环境中进行实际编程(C语言),完成发送程序、接收程序的编写,并进行收发场景的实际效果演示。
什么是隐蔽通道呢?简单的说就是允许进程以违反系统安全策略的方式传递信息的信道。一般而言,有存储隐蔽通道和时间隐蔽通道两种。
在具体的实验环境中有这样2点约束:

(1)高级用户可以读低安全级文件,但是不能创建低安全级文件,也不能通过拷贝等方式向下传递信息。【不可下写】
(2)低级用户无法读高安全级文件。【不可上读】
那么高级用户要把机密信息传递给低级用户,就只有通过隐蔽通道,绕过OS的DAC,MAC机制。通常可以选用进程标识符、文件最近访问时间,消息队列等信道,这里我选择文件最近访问时间这一隐蔽通道来实现场景演示。
如何选择文件最近访问时间作为隐蔽通道呢?
首先,我们需要明确每当用户进程访问一个文件时,系统内核都会更新该文件的最近访问时间。并且根据系统的安全策略,允许高安全级用户读低安全级的文件,低安全级用户的可以察觉到这种访问。
如此一来,高安全级用户可以读取机密文件,根据该文件内容的当前字节的2进制位信息决定怎样访问的低安全级用户的文件,而低安全级用户则可以检测到哪些文件的最近访问时间被修改,从而还原出高安全级用户发送的字节。
例如假设低安全级用户创建了b1到b8一共8个文件,高安全级用户读取到“A”,“A”的ASCII码为65,即01000001,因此高安全级用户访问b1和b7两个文件。低安全级用户检测到b1和b7的最近访问时间变化了,而其余文件的最近访问时间不变,故可以还原出01000001,即可得到“A”。
可见,上述利用最近访问时间的方案是非常直观的,主要瓶颈在于最近修改时间只能精确到秒,所以一定程度上使得此信道的传输率较低。思路是清晰的,道路却是曲折的。在实现过程中,需要考虑发送端和接受端的同步,以及重传纠错机制,增强程序的健壮性。
下面给出具体实现的有限自动机说明:

发送端:
image
描述:
S1:
发送端启动,检测start文件是否存在,若存在则进入S2,若不存在则停留在S1。

S2: 读取机密文件dataIn一个字节,判断是否EOF,若是则进入S3,若不是则进入S4。

S3: 修改end文件的最近访问时间并结束。

S4: 先修改byteBegin文件的最近访问时间,再根据读入的字节的2进制位信息修改对应的b1–b8的最近访问时间,最后修改byteEnd文件的最近访问时间,并进入S5。

S5: 检测temp文件的最近访问时间是否更新,若更新则进入S6,若未更新则停留在S5。

S6: 判断temp文件中写入的数据是否为刚才发送的一个字节。若是则修改right文件的最近访问时间,并进入S2读取下一个字节;若不是则修改wrong文件的最近访问时间,并进入S4重传。

接收端:
image

描述:

在进入有限状态自动机之前,先创建start文件,通知发送端可进行数据传输。

S1: 检测end文件的最近访问时间是否更新,若是则进入S2;若不是则检测byteBegin文件的最近访问时间是否更新,若是则进入S3,若不是则停留在S1。

S2: 删除start文件并结束。

S3: 检测byteEnd文件的最近访问时间是否更新,若是则进入S4,若不是则停留在S3。

S4: 根据文件b1–b8最近访问时间的修改情况,还原出发送端发送的数据,并写入temp文件,进入S5。

S5: 检测right文件和wrong文件的最近访问时间,以此判断所接收的数据是否正确。若正确则进入S6,若不正确则进入S3,等待发送端重传。

S6: 将接收到的一个字节写入dataOut中,并进入S1,等待发送端发送下一个字节。

ps:其实可以将没有事件触发的状态合并,因此发送端可化简为只有5个状态,接受端可化简为只有4个状态。考虑到代码实现的清晰性和未来的扩展性,最后还是没有化简,嘿嘿。  为了增加传输速率,也可以多创建几个文件,比如b1-b32,一次性发送4个字节。但这样无疑增大了纠错重传机制的难度,需要像网络中的tcp一般引入滑动窗口机制等等,偷个懒,没有写那么复杂,嘿嘿,有兴趣的同学可以试试,然后交流交流,
源代码附后:

server.c

   1: /*
   2:     Filename: server.c
   3:
   4:     Author:     foelin (foeln@gmail.com)
   5:     Company:    ISCAS
   6:     Date:       2008/12/3
   7:     
   8:     Description:
   9:         在SECLinux中高权限用户不可下写,低权限用户不可上读。因此高权限用户通过隐蔽通道将机密文件发送为低优先级用户
  10:          本程序是高权限发送端,利用文件的最近修改时间作为隐蔽通道
  11: */
  12: #include<stdio.h>
  13: #include<stdlib.h>
  14: #include<sys/types.h>
  15: #include<sys/stat.h>
  16: #include<unistd.h>
  17: #include<utime.h>
  18:
  19: /*---------------------------------------------------------
  20:     相关文件说明(以下所有文件除dataIn在高权限用户的目录下,其余均在低权限用户的目录下)
  21:     
  22:     start文件由client在运行时创建并删除,chmod为777
  23:
  24:     end, byteBegin, byteEnd, right, wrong, temp, b1-b8全部由低权限用户预先创建,并chmod为777
  25:
  26:     dataIn是server将要发送给client的机密文件。    
  27:
  28: ----------------------------------------------------------*/
  29: //TODO: modify the macro to your own high an low dir
  30: #define LOW_DIR "/home/uLow/WZH/"
  31: #define HIGH_DIR "/home/uHigh/WZH/"
  32:
  33:
  34: const char* start = LOW_DIR    "start";                //client准备好接受数据后,创建该文件
  35: const char* end = LOW_DIR    "end";                    //当发送完毕后,server修改此文件的最近访问时间
  36: const char* byteBegin = LOW_DIR    "byteBegin";        //当开始发送一个字节时,server修改此文件的最近访问时间
  37: const char* byteEnd = LOW_DIR    "byteEnd";            //当发送完一个字节后,server修改此文件的最近访问时间
  38: const char* right = LOW_DIR    "right";                //当校验client接受的数据正确后,server修改此文件的最近访问时间
  39: const char* wrong = LOW_DIR    "wrong";                //当校验client接受的数据错误后,server修改此文件的最近访问时间
  40: const char* temp = LOW_DIR    "temp";                    //临时文件,client收到一个字节后先写入此文件,server读此文件一个字节,判断client是否接受正确
  41: const char* bit[8] = {LOW_DIR "b1", LOW_DIR "b2", LOW_DIR  "b3", LOW_DIR  "b4", LOW_DIR  "b5", LOW_DIR  "b6", LOW_DIR  "b7", LOW_DIR  "b8"};    //b1 - b8表示server读到的一个字节的1到8位
  42: const char* dataIn = HIGH_DIR "dataIn";                //含有将要传输给client的数据的文件
  43:
  44: /*------------------------------------------------
  45:         取得文件的最近访问时间
  46: -------------------------------------------------*/
  47: unsigned long getLastAccessTime(const char* fn)
  48: {
  49:     struct stat st;
  50:     if(0 != stat(fn, &st))
  51:     {
  52:         printf("file status info can't be obtained!n");
  53:         exit(-1);
  54:     }
  55:
  56:     return st.st_atime;
  57:
  58: }
  59:
  60: /*------------------------------------------------
  61:         修改文件的最近访问时间
  62:         不能使用utime函数修改低权限目录下的文件访问时间
  63:         采用读一个字节的方案
  64: -------------------------------------------------*/
  65: void accessFile(const char* fn)
  66: {
  67:     /* 错误代码
  68:     struct stat st;
  69:     struct utimbuf buf;
  70:     if(0 != stat(fn, &st))
  71:     {
  72:         printf("file status info can't be obtained!n");
  73:         exit(-1);
  74:     }
  75:
  76:     buf.modtime = st.st_mtime;
  77:     buf.actime = st.st_atime - 10;
  78:
  79:     if(0 != utime(fn, &buf))
  80:     {
  81:         printf("can not update the %sn", fn);
  82:         exit(-1);
  83:     }
  84:     */
  85:
  86:     char buf;
  87:     unsigned long atime;
  88:     FILE * pf;
  89:
  90:     atime = getLastAccessTime(fn);
  91:     pf = fopen(fn, "r");
  92:     if(!pf)
  93:     {
  94:         printf("file not exist: %s", fn);
  95:         exit(-1);
  96:     }
  97:
  98:     fread(&buf, 1, 1, pf);
  99:     while(atime == getLastAccessTime(fn))
 100:     {
 101:         usleep(1000);    //0.001 second
 102:         fread(&buf, 1, 1, pf);
 103:     }
 104:     fclose(pf);
 105: }
 106:
 107: /*------------------------------------------------
 108:         判断一个文件是否存在
 109: -------------------------------------------------*/
 110: int isExist(const char* fn)
 111: {
 112:     FILE* fp;
 113:     fp = fopen(fn, "r");
 114:
 115:     if(fp == NULL)
 116:     {
 117:         printf("%s is not exist!n", fn);
 118:         return 0;
 119:     }
 120:     else
 121:     {
 122:         fclose(fp);
 123:         return 1;
 124:     }
 125: }
 126:
 127: /*------------------------------------------------
 128:         main函数,利用有限状态自动机实现
 129: -------------------------------------------------*/
 130: int main()
 131: {
 132:     int state;
 133:     FILE* dataInFp, *tempFp;
 134:     int c, tempC;
 135:     int i;
 136:     unsigned long lastTempT;
 137:
 138:     printf("server start!n");
 139:
 140:     state = 1;
 141:     printf("state = 1n");
 142:     while(1)
 143:     {
 144:         switch(state)
 145:         {
 146:             case 1:
 147:             {
 148:                 if(isExist(start))
 149:                 {
 150:                     dataInFp = fopen(dataIn,"r");    //打开数据文件
 151:                     if(!dataInFp)
 152:                     {
 153:                         printf("data file:%s is not exist!n", dataIn);
 154:                         exit(-1);
 155:                     }
 156:                     lastTempT = getLastAccessTime(temp);    //取得临时纠错文件的上一次访问时间
 157:                     state = 2;
 158:                     printf("state = 2n");
 159:                     }
 160:                 else
 161:                 {
 162:                     sleep(1);        //等待1秒钟
 163:                 }
 164:             }
 165:             break;
 166:
 167:             case 2:
 168:             {
 169:                 if((c=fgetc(dataInFp)) != EOF)
 170:                 {
 171:                     state = 4;
 172:                     printf("state = 4n");
 173:                 }
 174:                 else    //文件结束
 175:                 {
 176:                     state = 3;
 177:                     printf("state = 3n");
 178:                 }
 179:             }
 180:             break;
 181:
 182:             case 3:
 183:             {
 184:                 //修改结束文件
 185:                 accessFile(end);
 186:                 fclose(dataInFp);
 187:                 printf("server over!n");
 188:                 return 0;
 189:             }
 190:             break;
 191:
 192:             case 4:
 193:             {
 194:                 accessFile(byteBegin);        //首先发送byteBegin的消息,表示发送方开始发送一个字节
 195:                 for(i=0; i<8; i++)
 196:                 {
 197:                     if((c & (1<<i)) != 0)
 198:                         accessFile(bit[i]);
 199:                 }
 200:                 accessFile(byteEnd);        //发送byteEnd消息,表示发送方已经发送完毕一个字节
 201:                 state = 5;
 202:                 printf("state = 5n");
 203:             }
 204:             break;
 205:
 206:             case 5:
 207:             {
 208:                 unsigned long t = getLastAccessTime(temp);
 209:                 if(t != lastTempT)
 210:                 {
 211:                     state = 6;    //暂时不记录新的accesstime,因为在状态6时,server要访问该文件
 212:                     printf("state = 6n");
 213:                 }
 214:             }
 215:             break;
 216:
 217:             case 6:
 218:             {
 219:                 tempFp = fopen(temp, "r");
 220:                 tempC = fgetc(tempFp);
 221:
 222:                 if(tempC == c)
 223:                 {
 224:                     accessFile(right);
 225:                     state = 2;
 226:                     printf("right send: [%c]n", c);
 227:                     printf("state = 2n");
 228:                 }
 229:                 else
 230:                 {
 231:                     accessFile(wrong);
 232:                     state = 4;
 233:                     printf("wrong send: [%c]!  resend it!n", c);
 234:                     printf("state = 4n");
 235:                 }
 236:
 237:                 fclose(tempFp);
 238:                 lastTempT = getLastAccessTime(temp);
 239:                 //记录此时temp文件的最后访问时间
 240:             }
 241:             break;
 242:
 243:             default:
 244:                 printf("errors!n");
 245:             break;
 246:         }//end switch    
 247:     }// end while
 248:     return 0;
 249: }

client.c

   1: /*
   2:     Filename:    client.c
   3:
   4:     Author:      foelin (foeln@gmail.com)
   5:     Company:     ISCAS
   6:     Date:        2008/12/3
   7:     
   8:     Description:
   9:         在SECLinux中高权限用户不可下写,低权限用户不可上读。因此高权限用户通过隐蔽通道将机密文件发送为低优先级用户
  10:          本程序是低权限接收端,利用文件的最近修改时间作为隐蔽通道
  11:
  12: */
  13: #include<stdio.h>
  14: #include<stdlib.h>
  15: #include<sys/types.h>
  16: #include<sys/stat.h>
  17: #include<unistd.h>
  18: #include<utime.h>
  19:
  20: /*---------------------------------------------------------
  21:     相关文件说明(以下所有文件均在低权限用户的目录下)
  22:     
  23:     start文件由client在运行时创建并删除,chmod为777
  24:
  25:     end, byteBegin, byteEnd, right, wrong, temp, b1-b8全部由低权限用户预先创建,并chmod为777
  26:
  27:     dataOut在client接受完数据后创建    
  28:
  29: ----------------------------------------------------------*/
  30: //TODO: modify the macro to your own high an low dir
  31: #define LOW_DIR "/home/uLow/WZH/"
  32: #define HIGH_DIR "/home/uHigh/WZH/"
  33:
  34: const char* start = LOW_DIR "start";            //client准备好接受数据后,创建该文件
  35: const char* end = LOW_DIR "end";                //当发送完毕后,server修改此文件的最近访问时间
  36: const char* byteBegin = LOW_DIR "byteBegin";    //当开始发送一个字节时,server修改此文件的最近访问时间
  37: const char* byteEnd = LOW_DIR "byteEnd";        //当发送完一个字节后,server修改此文件的最近访问时间
  38: const char* right = LOW_DIR "right";            //当校验client接受的数据正确后,server修改此文件的最近访问时间
  39: const char* wrong = LOW_DIR "wrong";            //当校验client接受的数据错误后,server修改此文件的最近访问时间
  40: const char* temp = LOW_DIR "temp";                //临时文件,client收到一个字节后先写入此文件,server读此文件一个字节,判断client是否接受正确
  41: const char* bit[8] = {LOW_DIR "b1", LOW_DIR "b2", LOW_DIR  "b3", LOW_DIR  "b4", LOW_DIR  "b5", LOW_DIR  "b6", LOW_DIR  "b7", LOW_DIR  "b8"};    //b1 - b8表示server读到的一个字节的1到8位
  42: const char* dataOut = LOW_DIR "dataOut";        //保存从server接受到的数据的文件
  43:
  44: /*------------------------------------------------
  45:         取得文件的最近访问时间
  46: -------------------------------------------------*/
  47: unsigned long getLastAccessTime(const char* fn)
  48: {
  49:     struct stat st;
  50:     if(0 != stat(fn, &st))
  51:     {
  52:         printf("file %s status info can't be obtained!n", fn);
  53:         exit(-1);
  54:     }
  55:
  56:     return st.st_atime;
  57: }
  58:
  59: /*------------------------------------------------
  60:         修改文件的最近访问时间
  61:         由于是修改自己owners权限下的文件,所以可以使用utime函数
  62: -------------------------------------------------*/
  63: void accessFile(const char* fn)
  64: {
  65:     struct stat st;
  66:     struct utimbuf buf;
  67:     if(0 != stat(fn, &st))
  68:     {
  69:         printf("file status info can't be obtained!n");
  70:         exit(-1);
  71:     }
  72:
  73:     buf.modtime = st.st_mtime;    //最近修改时间不变
  74:     buf.actime = st.st_atime - 10;  //最近访问时间改变
  75:
  76:     if(0 != utime(fn, &buf))
  77:     {
  78:         printf("can not update the %sn", fn);
  79:         exit(-1);
  80:     }
  81: }
  82:
  83: /*------------------------------------------------
  84:         main函数,利用有限状态自动机实现
  85: -------------------------------------------------*/
  86: int main()
  87: {
  88:     int i;
  89:     int state;
  90:     unsigned long lastByteBegin, lastByteEnd, lastEnd, lastRight, lastWrong;
  91:     unsigned long lastBit[8];
  92:     unsigned long tempT1, tempT2;
  93:     unsigned long tempBit[8];
  94:     int c;
  95:
  96:     FILE *dataOutFp, *tempFp, *startFp;
  97:
  98:     //创建保存接受到的数据的文件
  99:     if(!(dataOutFp = fopen(dataOut, "w")))
 100:     {
 101:         printf("can not create file: %sn", dataOut);
 102:         exit(-1);
 103:     }
 104:
 105:     //创建start文件,表示receiver开始运行
 106:     if(!(startFp = fopen(start, "w")))
 107:     {
 108:         printf("can not create file: %sn", start);
 109:         exit(-1);
 110:     }
 111:     fputc('0', startFp);
 112:     fclose(startFp);
 113:
 114:     //chmod,因为默认情况下创建的文件是只有属主能读写运行
 115:     struct stat st;
 116:     mode_t mt;
 117:     stat(start,&st);
 118:     mt=st.st_mode;
 119:     mt|=0x1ff;
 120:     chmod(start,mt);    // chmod 777 start
 121:
 122:     //取最近访问时间
 123:     lastByteBegin = getLastAccessTime(byteBegin);
 124:     lastByteEnd = getLastAccessTime(byteEnd);
 125:     lastEnd = getLastAccessTime(end);
 126:     lastWrong = getLastAccessTime(wrong);
 127:     lastRight = getLastAccessTime(right);
 128:     for(i=0; i<8; i++)
 129:     {
 130:         lastBit[i] = getLastAccessTime(bit[i]);
 131:     }
 132:
 133:     printf("client start!n");
 134:
 135:     state = 1;
 136:     printf("state = 1n");
 137:     while(1)
 138:     {
 139:         switch(state)
 140:         {
 141:             case 1:
 142:             {
 143:                 tempT1 = getLastAccessTime(byteBegin);
 144:                 if(tempT1 != lastByteBegin)    //发送方已经开始发送
 145:                 {
 146:                     lastByteBegin = tempT1;
 147:                     state = 3;
 148:                     printf("state = 3n");
 149:                 }
 150:                 else
 151:                 {
 152:                     tempT2 = getLastAccessTime(end);
 153:                     if(tempT2 != lastEnd) //进入结束状态,否则仍然停留在状态1
 154:                     {
 155:                         lastEnd = tempT2;
 156:                         state = 2;
 157:                         printf("state = 2n");
 158:                     }
 159:                 }
 160:             }
 161:             break;
 162:
 163:             case 2:
 164:             {
 165:                 //删除开始文件
 166:                 if(0 != remove(start))
 167:                     printf("remove file %s error!n", start);
 168:
 169:                 fclose(dataOutFp);
 170:                 printf("client over!n");
 171:                 return 0;
 172:             }
 173:             break;
 174:
 175:             case 3:
 176:             {
 177:                 tempT1 = getLastAccessTime(byteEnd);
 178:                 if(tempT1 != lastByteEnd)    //发送方已经发送完毕,则进入状态3,否则等待
 179:                 {
 180:                     lastByteEnd = tempT1;
 181:                     state = 4;
 182:                     printf("state = 4n");
 183:                 }
 184:             }
 185:             break;
 186:
 187:             case 4:
 188:             {
 189:                 //读取信息
 190:                 for(i=0; i<8; i++)
 191:                     tempBit[i] = getLastAccessTime(bit[i]);
 192:
 193:                 c = 0;
 194:                 for(i=0; i<8; i++)
 195:                 {
 196:                     if(tempBit[i] != lastBit[i])//第i位为1
 197:                     {
 198:                         c |= (1<<i);
 199:                         lastBit[i] = tempBit[i];    //更新该文件的最后访问时间
 200:                     }
 201:                 }
 202:
 203:                 //写入临时文件
 204:                 tempFp = fopen(temp,"w");
 205:                 fputc(c, tempFp);
 206:                 fclose(tempFp);
 207:                 accessFile(temp);    //此句需保留,因为若往temp中写入c的时间小于1秒,则temp的最近访问时间不会更新。
 208:                 state = 5;
 209:                 printf("state = 5n");
 210:             }
 211:             break;
 212:
 213:             case 5:
 214:             {
 215:                 //判断检查信号
 216:                 tempT1 = getLastAccessTime(right);
 217:                 tempT2 = getLastAccessTime(wrong);
 218:                 if(tempT1 != lastRight)
 219:                 {
 220:                     lastRight = tempT1;
 221:                     state = 6;
 222:                     printf("right read: [%c]n", c);
 223:                     printf("state = 6n");
 224:                 }
 225:                 else if(tempT2 != lastWrong )
 226:                 {
 227:                     lastWrong = tempT2;
 228:                     state = 1;
 229:                     printf("wrong read: [%c]!  discard it!n", c);
 230:                     printf("state = 1n");
 231:                 }
 232:                 //若right和wrong都没有改变,则停留在此状态,继续检查
 233:             //    printf("in state 5n");
 234:             }
 235:             break;
 236:
 237:             case 6:
 238:             {
 239:                 fputc(c, dataOutFp);
 240:                 fflush(dataOutFp);
 241:                 state = 1;
 242:                 printf("state = 1n");
 243:             }
 244:             break;
 245:         }// end switch
 246:     }// end while
 247:
 248:     return 0;
 249: }
 250:
 251:
最后:
话说很久没有写有关学习或者技术的文章,期末考试临近,本文便算是好好复习的一个前奏吧~~
UPDATE @ 2008/12/8
1.更新了server.c和client.c中的accessFile函数。原来是不停地fgetc,直到st_atime发生改变,这样比较慢,并且至少需要1秒钟。现在改成了用utime函数,直接修改st_atime,提高了效率。
2.去掉server.c里面进入state 5时,检测temp的st_atime不变时sleep(1),避免无谓的等待。
修改后传输速度提高数倍。

UPDATE @ 2009/5/3
修改了server.c里面accessFile函数。由于高权限用户不能使用utime函数修改atime,所以只能还是用传统的open->read->close的方式来改变最近访问时间。
当初最开始实验的时候就是用的传统方式,在SECLinux下测试通过,后来UPDATE@ 2008/12/8时候仅仅在普通linux下测试通过了,没有在SECLinux下测试,所以造成了这个错误。感谢justin同学指正。
client对自己所属的文件可以调用utime函数修改atime,所以维持不变。
UPDATE @ 2009/5/15
注意,本程序的运行环境是安胜OS,即SECLinux。在普通linux下没有“不可下写”的限制,所以通过这种隐蔽通道传递信息无意义。并且由于普通linux的fread不能改变atime,所以上述程序也不能正确运行。
UPDATE @ 2009/11/29
发现了个小问题,所有的printf里面的反斜杠都被wordpress屏蔽掉了,例如’\n’都成了’n',大家自己改一下吧~

Creative Commons License
This work, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-No Derivative Works 2.5 China Mainland License.
标签:, ,
此条目发表在 学无止境 分类目录,贴了 , , 标签。将固定链接加入收藏夹。

OSS实验 隐蔽通道场景演示》有 13 条评论

  1. 3greens 说:

    :?: 楼主你好,很高兴能在茫茫的网络中找到您这篇很有收获的文章,对隐蔽通道我一直想学习,只是相关的书籍材料很欠缺,看到您这篇文章我很有收获。只是对其中的一些地方不太理解,希望得到您的指点:
    1.在上述的代码中我看到您是通过高进程修改低权限用户下的文档传输隐蔽信息的,我感到疑惑的是这样做是不是违背了不下写不上读的原则。(也许我没看懂,望您指教)。
    2.我想如果通过文件读写锁来实现传输,即高进程打开文档,低进程写不成功则传输一个信息。该运用那些函数进行?
    由于我还是新手,对编程问题不太理解,希望得到您详细的指教。
    非常感谢!

    回复

    foelin reply on 四月 29th, 2009:

    你好~
    1.上述代码并没有通过高进程修改低权限用户下面的文档。
    如果你说的是accessFile函数,那么你就理解错了。accessFile里面只是通过buf.actime = st.st_atime – 10;来简单的修改了文件的最近访问时间。等效于你fopen后fread一个字节然后fclose。也就是说读操作也会改变文件的最近访问时间。所以这里其实是利用了“读”,并没有违反“不可下写”的约束

    2.文件读写锁方面的内容,你可以参考《Unix环境高级编程》chap12关于高级IO的内容

    回复

    3greens reply on 五月 5th, 2009:

    谢谢,我大概了解了,会常来关注的,希望你写出更多精彩的帖子。

    回复

  2. justin 说:

    utime是需要写权限的吧,这样貌似不行诶

    回复

    foelin reply on 五月 2nd, 2009:

    应该可以的
    改成fread一个byte也行

    回复

  3. justin 说:

    我试了下你的源码,在没有禁止高读低写的的Linux环境下是OK的,但在安胜下utime貌似不行。

    回复

    foelin reply on 五月 3rd, 2009:

    恩,确实不行,重新装了安胜测试了下~~
    现在已经修改过来了~
    感谢提醒 :grin:

    回复

    justin reply on 五月 3rd, 2009:

    不谢不谢,你写的非常棒~~赞一个

    回复

  4. 3greens 说:

    楼主,能否解释一下下面的代码,我尝试过,似乎一直在等待,也没有发现修改了访问时间。谢谢

    86: char buf;
    87: unsigned long atime;
    88: FILE * pf;
    89:
    90: atime = getLastAccessTime(fn);
    91: pf = fopen(fn, “r”);
    92: if(!pf)
    93: {
    94: printf(“file not exist: %s”, fn);
    95: exit(-1);
    96: }
    97:
    98: fread(&buf, 1, 1, pf);
    99: while(atime == getLastAccessTime(fn))
    100: {
    101: usleep(1000); //0.001 second
    102: fread(&buf, 1, 1, pf);
    103: }
    104: fclose(pf);

    回复

  5. 3greens 说:

    楼主你好,上次提出问题后一直在等待您的指点,没有得到消息,可能是您最近比较忙吧,我盼望您能在百忙中关注一下这个问题,针对楼上提出的代码我确实存在一些疑惑,我在fedora 9下实验原来代码能够成功,但实验您最新更改的代码,发现读取文件时并没有引起文件最近访问时间的改变,实验很多次没有成功,也可能是我实验的环境存在问题,所以我盼望能得到您的指点。还有我上次提的问题:我打算通过读写互斥达到隐蔽传递,但简单的open,read,write函数似乎并不能达到互斥效果,后来我有调用fcntl函数加锁,但仍然无果,因我毕业设计与此相关,所以屡屡麻烦您,期待得到您的指导。
    诚挚感谢

    回复

    foelin reply on 五月 15th, 2009:

    你好~
    我刚在SECLinux下面试验了一下,上述代码是可以运行成功的,fread是可以修改atime的。如果质疑的话,我可以截图给你看看,呵呵
    不过我也在普通linux下试了下,确实fread不能改atime……
    由于本文的前提是SECLinux下的隐蔽通道分析,所以是满足要求的。普通linux下没有不可下写的限制,所以也没有必要用这种方式传递信息。并且原来那种方法,在SECLinux下是行不通的,utime需要权限~~
    PS:
    其实还有很多隐蔽通道,例如还可以使用进程标识符信道,发送方读取机密文件,然后,根据该文件内容的当前字节的ASIIC码决定创建的子进程数目,待接收方读取该信息后,删除这些子进程。

    回复

    3greens reply on 五月 26th, 2009:

    谢谢您多次的指导,我已经基本了解了,屡次麻烦您,却得到您的耐心指导,让我很感动,会常来您这里学习,也希望能常与您探讨更多知识。祝工作顺利。

    回复

    foelin reply on 五月 28th, 2009:

    不客气~~
    彼此学习吧·~
    祝好·

    回复

发表评论

电子邮件地址不会被公开。 必填项已被标记为 *

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>