软件安全实验pre1(常用linux命令和函数)

1.

写出一行linux命令列出根目录下所有suid程序。描述linux下setuid/seteuid/setreuid/getenv这几个函数的功能和差异。

解答:

(1)

find / -perm -04000 -type f -ls
在这里插入图片描述

函数说明:

(2)setuid函数

setuid()用来重新设置执行目前进程的用户识别码。
不过,要让此函数有作用,其有效的用户识别码必须为0(root)。在Linux下,当root 使用setuid()来变换成其他用户识别码时,root权限会被抛弃,完全转换成该用户身份,也就是说,该进程往后将不再具有可setuid()的权 利,如果只是向暂时抛弃root 权限,稍后想重新取回权限,则必须使用seteuid()。
返回值:执行成功则返回0,失败则返回-1,错误代码存于errno
注意:一般在编写具setuid root的程序时,为减少此类程序带来的系统安全风险,在使用完root权限后建议马上执行setuid(getuid());来抛弃root权限。此外,进程uid和euid不一致时Linux系统将不会产生core dump

(3)seteuid函数

seteuid(设置有效的用户识别码)
函数说明 :seteuid()用来重新设置执行目前进程的有效用户识别码。在Linux下,seteuid(euid)相当于setreuid(-1,euid)。
返回值: 执行成功则返回0,失败则返回-1,错误代码存于errno
附加说明: 请参考setuid()

(4)setreuid函数

#include <unistd.h>
setreuid(uid_t ruid, uid_t euid)
函数说明:
来设定真实用户ID(real uid)和有效用户ID(effective uid),这个函数在由有效用户ID符为0的进程调用时,不会改变已保存用户ID。
注意:函数seteuid(uid_t uid)等价于setreuid(-1,uid),只改变有效用户ID(effective uid)。

(5)getenv函数

linux下的getenv()函数是个获取变量的函数,常用于linux下的C语言编程,不同于shell下使用env指令获取的环境变量。
这个函数主要用于获取网络相关的环境变量。

2.

有些入侵者入侵系统后,喜欢隐藏一个suid root shell文件以便下次再进入。对于这种后门应该如何进行检测?

解答:

系统管理员应该定期查看系统中有哪些 SUID 和 SGID文件,可以用下面的命令实现:

find / -type f ( -perm -4000 -o -perm -2000 ) –print。
在这里插入图片描述

3.

Gdb一个suid程序,该程序在被gdb调试执行时是否依然拥有文件owner权限?解释原因。

解答:具有 owner权限,因为它执行该文件时其 effective user ID置为 owner的id

4(2018).

解释Linux环境变量PATH的作用,如何显示和修改这个环境变量? 解释linux用root执行下面这条命令
chmod 4755 file
的含义和用途。

(1)关于PATH的作用:

PATH说简单点就是一个字符串变量,当输入命令的时候LINUX会去查找PATH里面记录的路径。比如在根目录/下可以输入命令ls,在/usr目录下也可以输入ls,但其实ls这个命令根本不在这个两个目录下,事实上当你输入命令的时候LINUX会去/bin,/usr/bin,/sbin等目录下面去找你此时输入的命令,而PATH的值恰恰就是/bin:/sbin:/usr/bin:……。其中的冒号使目录与目录之间隔开。

可以用echo $PATH命令查看PATH的值。
在这里插入图片描述

关于新增自定义路径:
现在假设你新安装了一个命令在/usr/locar/new/bin下面,而你又想像ls一样在任何地方都使用这个命令,你就需要修改环境变量PATH了,准确的说就是给PATH增加一个值/usr/locar/new/bin。你只需要一行bash命令export PATH=$PATH:/usr/locar/new/bin。这条命令的意思太清楚不过了,使PATH自增:/usr/locar/new/bin,既PATH=PATH+":/usr/locar/new/bin";通常的做法是把这行bash命令写到/root/.bashrc的末尾,然后当你重新登陆LINUX的时候(应该是linux启动时就会执行这个文件),新的默认路径就添加进去了。当然这里你直接用source /root/.bashrc执行这个文件重新登陆了。

关于删除自定义路径:
当某天你发现你新增的路径/usr/locar/new/bin已经没用了的话,你可以修改/root/.bashrc文件里面你新增的路径。或者你可以修改/etc/profile文件删除你不需要的路径.
linux查看和修改PATH环境变量的方法

查看PATH:echo P A T H 以 添 加 m o n g o d b s e r v e r 为 列 修 改 方 法 一 : e x p o r t P A T H = / u s r / l o c a l / m o n g o d b / b i n : PATH 以添加mongodb server为列 修改方法一: export PATH=/usr/local/mongodb/bin: PATHmongodbserverexportPATH=/usr/local/mongodb/bin:PATH
//配置完后可以通过echo $PATH查看配置结果。
生效方法:立即生效
有效期限:临时改变,只能在当前的终端窗口中有效,当前窗口关闭后就会恢复原有的path配置
用户局限:仅对当前用户

修改方法二:
通过修改.bashrc文件:
vim ~/.bashrc
//在最后一行添上:
export PATH=/usr/local/mongodb/bin:$PATH
生效方法:(有以下两种)
1、关闭当前终端窗口,重新打开一个新终端窗口就能生效
2、输入“source ~/.bashrc”命令,立即生效
有效期限:永久有效
用户局限:仅对当前用户

修改方法三:
通过修改profile文件:
vim /etc/profile
/export PATH //找到设置PATH的行,添加
export PATH=/usr/local/mongodb/bin:$PATH
生效方法:系统重启
有效期限:永久有效
用户局限:对所有用户

修改方法四:
通过修改environment文件:
vim /etc/environment
在PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"中加入“:/usr/local/mongodb/bin”
生效方法:系统重启
有效期限:永久有效
用户局限:对所有用户

(2)

chmod是Linux下设置文件权限的命令,后面的数字表示不同用户或用户组的权限。
第一个数字表示文件所有者的权限
第二个数字表示与文件所有者同属一个用户组的其他用户的权限
第三个数字表示其它用户组的权限。
权限分为三种:读(r=4),写(w=2),执行(x=1)。综合起来还有可读可执行(rx=5=4+1)、可读可写(rw=6=4+2)、可读可写可执行(rwx=7=4+2+1)。

所以chmod 4755 设置用户的权限为:
这个4表示其他用户执行文件时,具有与所有者相当的权限。
7表示文件所有者可读可写可执行
5表示与文件所有者同属一个用户组的其他用户可读可执行
5表示其它用户组可读可执行

5(2018).

描述system、execve、fork这几个函数的功能和差异。

(1)启动新进程(system函数):

system()函数可以启动一个新的进程。
int system (const char *string )
这个函数的效果就相当于执行sh –c string。
一般来说,使用system函数远非启动其他进程的理想手段,因为它必须用一个shell来启动需要的程序。这样对shell的安装情况,以及shell的版本依赖性很大。
system函数的特点:
建立独立进程,拥有独立的代码空间,内存空间
等待新的进程执行完毕,system才返回。(阻塞)

(2)替换进程映像(exec函数):

exec函数可以用来替换进程映像。执行exec系列函数后,原来的进程将不再执行,新的进程的PID、PPID和nice值与原先的完全一样。其实执行exec系列函数所发生的一切就是,运行中的程序开始执行exec调用中指定的新的可执行文件中的代码。
exec函数的特点:
当进程调用一种exec函数时,源进程完全由新程序代换,而新程序则从其main函数开始执行。因为调用exec并不创建新进程,所以前后的进程ID并未改变。exec只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。特别地,在原进程中已经打开的文件描述符,在新进程中仍将保持打开,除非它们的“执行时关闭标志”(close on exec flag)被置位。任何在原进程中已打开的目录流都将在新进程中被关闭。

(3)复制进程映像(fork函数):

fork函数
头文件
#include<unistd.h>
#include<sys/types.h>
函数原型
pid_t fork( void);
返回值:
若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1

关于fork函数的作用:
我们可以通过调用fork创建一个新进程。这个系统调用复制当前进程,在进程表中新建一个新的表项,新表项中的许多属性与当前进程是相同的。新进程几乎与元进程一模一样,执行的代码也完全相同,但是新进程有自己的数据空间、环境和文件描述符。

(4)system()、exec()、fork()函数比较

首先比较一下exec()函数和fork()。这两个函数一个是换药不换汤(execl函数),另一个是换汤不换药(fork函数)。那么什么是汤、什么又是药呢?我们知道进程是个很复杂的东西。从task_struct 结构体的代码量上就可以看出来(task_struct是Linux内核中用来描述进程的一个结构体,这个结构体光代码貌似就有好几屏)。我们可以把进程的PID、PPID和nice值等看作是汤,而把进程空间(简单理解就是正文段、数据段、堆、栈等)看作是药。

exec()函数是换药不换汤,就是说执行exec函数后,并没有产生新的进程,也就是汤还是那些汤,进程的PID、PPID和nice值等没有发生变化。但是exec()函数却将药换了,也就是将进程空间换掉了,新的进程空间是为了执行新的程序所准备的,所以新的进程空间与原进程空间并没有什么关系。

fork()函数是换汤不换药,意思是执行fork()函数后,产生了新的进程,新的进程的PID、PPID与原来原来的进程不同,说明父子进程是两个不同的进程,但是fork并没有把药换掉,而是将药复制了一份给子进程。fork刚执行后的一段时间内,父子进程有着相同的状态(进程空间中的东西都一样,因为fork采用“写时复制”,一开始父子进程共享物理内存空间)。但是一旦父子进程中有一个进程试图修改进程空间,这时父子进程就各自拥有了各自的进程空间,简单地理解,从这一时刻器,父子进程就是两个独立的进程,谁都不会影响谁(实际上还是有一定影响的,在这里可以忽略),父子进程之间的关联仅剩下它们共享的代码段了。

我们看到system()函数实际上就是先执行了fork函数,然后新产生的子进程立刻执行了exec函数,我们前面说个fork函数换汤不换药,exec函数换药不换汤,那么system函数就是既换汤也换了药,也就是system函数会产生新进程,这就意味着新进程的PID、PPID等与原进程不同。system也会产生新的进程空间,而且新的进程空间是为新的程序准备的,所以和原进程的进程空间没有任何关系(不像fork新进程空间是对原进程空间的一个复制)。还要注意的是,system函数代码中else部分执行了wait函数,这就意味着,原进程会等待子进程执行完毕(阻塞)

最后还要注意的一个问题是关于文件描述符的。
exec函数执行后,原来打开的文件描述符依然存在。
fork函数执行后,原来打开的文件描述符会复制一份到新的进程中,之后两个进程之间的文件描述符就相对独立了。
system函数先执行fork函数,这之后两个进程的文件描述符就相对独立了。之后exec函数并不影响文件描述符。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值