一、 实验内容
(1) 设想一种场景需要进行普通用户和root用户切换,设计程序实现euid的安全管理。配合第3章 完成进程中euid的切换,实现root权限临时性和永久性管理,加强程序的安全性
(2) 搭建安全的沙盒环境,在沙盒环境中提供必须的常见工具,并提供程序验证沙盒环境的安全性。配合第3章 实现系统中的虚拟化限制方法,实现安全的系统加固,测试虚拟化空间的加固程度
二、 实验设计
1.1 Linux系统文件和目录权限设置与辨识setuid程序uid差异
设计并实现不同用户对不同类文件的r、w、x权限,查看系统文件的权限设置:
a)查看/etc/passwd文件和/etc/bin/passwd文件的权限设置,并分析其权限为什么这么设置;
b)找到2个设置了setuid位的可执行程序,该程序的功能,该程序如果不设置setuid位是否能够达到相应的功能,
1.2 一些可执行程序运行时需要系统管理员权限,在UNIX中可以利用setuid位实现其功能,但setuid了的程序运行过程中拥有了root权限,因此在完成管理操作后需要切换到普通用户的身份执行后续操作。
(1)设想一种场景,比如提供http网络服务,需要设置setuid位,并为该场景编制相应的代码;
(2)如果用户fork进程后,父进程和子进程中euid、ruid、suid的差别;
(3)利用execl执行setuid程序后,euid、ruid、suid是否有变化;
(4)程序何时需要临时性放弃root权限,何时需要永久性放弃root权限,并在程序中分别实现两种放弃权限方法;
(5)execl函数族中有多个函数,比较有环境变量和无环境变量的函数使用的差异。
想说的话
这个实验不难,但是步骤非常复杂,
我把我的过程和实验报告写在下面的word文档中,
希望你动手写一写,用心看一看,不懂的地方积极查资料,
那样的话,你就一定能做到!
一定能感受到其中的乐趣!祝你成功!!
https://download.csdn.net/download/qinglingls/10936098
#include<sys/unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#define Err_sys(info) \
{ \
fprintf(stderr, "%s:%s\n", info, strerror(errno)); \
exit(EXIT_FAILURE); \
}
#define err_sys(info) \
{ \
fprintf(stderr, "pid==0:%s:%s\n", info, strerror(errno)); \
exit(EXIT_FAILURE); \
}
char *env_init[]={ "USER=unknown", "PATH=/tmp", NULL};
int main()
{ pid_t pid;
if((pid=fork())<0)
{Err_sys("fork error");}
else if(pid == 0) { /*specify path, specify environment */
if ( execle("/home/stevens/bin/echoall", "echoall", "myarg1",
"MY ARG2", (char *) 0 , env_init) < 0)
err_sys("fork error"); }
if(waitpid(pid,NULL,0)<0)
err_sys("wait error");
if((pid=fork())<0)
{Err_sys("fork error");}
else if (pid == 0) { /*specify path, specify environment */
if( execlp("echoall", "echoall", "only 1 args", (char *) 0 < 0))
err_sys("fork error"); }
exit(0);
}
Uid_change_test.c:
#include<sys/unistd.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#define Err_sys(info) \
{ \
fprintf(stderr, "%s:%s\n", info, strerror(errno)); \
exit(EXIT_FAILURE); \
}
#define err_sys(info) \
{ \
fprintf(stderr, "pid==0:%s:%s\n", info, strerror(errno)); \
exit(EXIT_FAILURE); \
}
#define ERROR_SYSCALL -1;
/**
* temporarily drop the uid to new_uid,and save uid now;
* setresuid:set real, effective and saved user or group ID
* return :
* ERROR_SYSCALL means:fail
* 0 means:success
**/
int drop_priv_temp(uid_t new_uid)
{
if(setresuid(-1,new_uid,geteuid())<0){
return ERROR_SYSCALL; }
//to verify the change
if(geteuid()!=new_uid){
return ERROR_SYSCALL; }
return 0;
}
/**
* permanetly drop the uid to new_uid,never come back;
* setresuid:set real, effective and saved user or group ID
* return :
* ERROR_SYSCALL means:fail
* 0 means:success
**/
int drop_priv_perm(uid_t new_uid)
{
int ruid,euid,suid;
if(setresuid(new_uid,new_uid,new_uid)<0){
return ERROR_SYSCALL; }
//to verify the change
if(getresuid(&ruid,&euid,&suid)<0){
return ERROR_SYSCALL; }
if(ruid != new_uid || euid != new_uid ||
suid != new_uid){
return ERROR_SYSCALL;}
return 0;
}
/**
* save uid
* return :
* ERROR_SYSCALL means:fail
* 0 means:success
**/
int restore_priv()
{
int ruid,euid,suid;
//to verify the change
if(getresuid(&ruid,&euid,&suid)<0){
return ERROR_SYSCALL; }
if(setresuid(-1,suid,-1) < 0){
return ERROR_SYSCALL;}
if(geteuid()!=suid){
return ERROR_SYSCALL;}
return 0;
}
char *env_init[]={ "USER=sakura", "PATH=/tmp", NULL};
int main(int argc,char* argv[])
{ pid_t pid;
uid_t new_uid=1000;
int ruid,euid,suid;
if((pid=fork())<0)
{Err_sys("fork error");}
else if(pid == 0) { /*specify path, specify environment */
if ( execle("/home/sakura/echoall", "echoall", "myarg1","MY ARG2", (char *) 0 , env_init) < 0)
{ err_sys("fork error"); }
}
if(waitpid(pid,NULL,0)<0)
err_sys("wait error");
if(getresuid(&ruid,&euid,&suid)<0){
err_sys("wait error"); }
printf("ruid:%d,euid:%d,suid:%d\n",ruid,euid,suid) ;
drop_priv_temp(new_uid);
if(getresuid(&ruid,&euid,&suid)<0){
err_sys("wait error"); }
printf("ruid:%d,euid:%d,suid:%d\n",ruid,euid,suid) ;
restore_priv();
if(getresuid(&ruid,&euid,&suid)<0){
err_sys("wait error"); }
printf("ruid:%d,euid:%d,suid:%d\n",ruid,euid,suid) ;
if((pid=fork())<0)
{Err_sys("fork error");}
else if (pid == 0) { /*specify path, specify environment */
if( execlp("/home/sakura/echoall", "echoall", "only 1 args", (char *) 0 < 0))
err_sys("fork error");
}
exit(0);
}
Echoall.c
int main(int argc,char *argv[])
{ int i;
char **ptr;
extern char **environ;
for (i=0;i<argc; i++) /* echo all command-line args*/
printf("argv[%d]: %s\n", i, argv[i]);
for (ptr=environ; *ptr!=0; ptr++) /* all env strings*/
printf("%s\n", *ptr);
exit(0);
}