首页 > 其他分享 >环境变量与set-uid实验

环境变量与set-uid实验

时间:2024-10-30 16:42:24浏览次数:1  
标签:bin set uid 程序 Set 进程 root 环境变量

 

 

 

作业题目

本实验室的学习目标是让学生了解环境变量如何影响程序以及系统行为。环境变量是一组动态命名值,可以影响正在运行的进程将在计算机上运行。大多数操作系统都使用它们,因为它们是1979年引入Unix。尽管环境变量会影响程序行为,但它们是如何实现的这一点很多程序员都不太理解。因此,如果程序使用环境变量程序员不知道它们被使用,程序可能有漏洞。

在本实验室中,学生将了解环境变量是如何工作的,它们是如何从父进程到子进程,以及它们如何影响系统/程序行为。我们特别感兴趣的是如何环境变量影响Set-UID程序的行为,这些程序通常是特权程序。

本实验室涵盖以下主题:

•环境变量

•SET-UID程序

•安全地调用外部程序

•能力泄漏

•动态加载程序/链接器

实验步骤及结果

Task 1: Manipulating Environment Variables

使用printenv打印环境变量:

1.1

使用printenv PWD打印出当前工作目录的路径:

1.2

使用export设置环境变量,unset删除环境变量:

1.3

Task 2: Passing Environment Variables from Parent Process to Child Process

fork()函数是Unix和Linux等操作系统中用于创建新进程的系统调用。它创建一个与原进程几乎完全相同的进程,新的进程称为子进程,原来的进程称为父进程。

在父进程中调用fork()函数,它将返回两次。在父进程中,fork()函数返回新创建的子进程的PID。在子进程中,fork()函数返回0。

编译运行题目给的代码myprintenv.c,会打印子进程的环境变量并存入文件file:

1.5

1.7

file:

1.4

创建代码myprintenv2.c,注释掉子进程case中的printenv(),取消父进程case中printenv()的注释,使它打印父进程的环境变量并存入file2:

1.6

1.7

file2:

1.8

对比file和file2:

1.11

在48行有不同:

1.9 1.10

可以看到,可执行文件名不同,但环境变量是相同的。

所以,父进程的环境变量会被子进程继承

Task 3: Environment Variables and execve()

execve()是一个系统调用,它可以用来执行一个新的进程,并通过替换当前进程的栈、堆、程序段和数据段,用新进程替换当前进程。execve() 会在当前进程中运行新程序。

execve()函数接收3个参数:①运行的指令;②指令用到的参数;③传入新程序的环境变量。

查看示例代码,argv[1]=NULL,也就是说,代码创建一个新程序并不向新程序传递任何环境变量。

1.2

编译并执行代码:

1.1

没有输出任何环境变量。

修改代码,将execve()的第三个参数修改为environ,environ(全局变量) 是一个指向环境变量字符串数组的指针,这个数组包含了所有当前进程可用的环境变量。也就是说,代码创建一个新程序并向新程序传递当前进程的环境变量。

捕获

编译并执行代码:

1.3

输出了环境变量。

所以,新进程通过execve()第三个参数的设置(environ)来继承原先进程的环境变量

Task 4: Environment Variables and system()

system()通过调用“/bin/sh -c command”命令来执行command,它使用execl()来执行/bin/sh,execl()会调用execve()并将环境变量数组传递给它。

所以,使用system(),会将当前进程的环境变量传递给新程序/bin/sh。如果当前进程有root的执行权限,那么得到的shell也会有root权限。

创建代码task.c,验证以上结论:

捕获

system()运行了一个新的shell程序,用shell执行“/usr/bin/env”,如果shell继承了调用程序的环境变量,就会输出。

编译并执行task.c:

task

输出了调用程序的环境变量。

所以,system()将调用进程的环境变量传递给新程序/bin/sh,验证完成。

Task 5: Environment Variable and Set-UID Programs

Set-UID程序是一种特权程序,它通过设置程序所有者为root,提升程序的权限,从而执行一些需要特权才能操作的文件或命令。

创建一个代码文件foo_seed.c:

aaa

它会打印当前进程的环境变量。

查看foo_seed.c的权限,它只有普通用户seed的权限:

1.7

修改环境变量PATH,LD_LIBRARY_PATH,和任意变量(dinner),并编译执行foo_seed:

1.8

1.9

打印出我们更改了的变量。

将foo_seed设置为Set-Uid程序,再次运行:

1.101.11

Set-Uid程序并没有继承被修改的LD_LIBRARY_PATH变量

LD_LIBRARY_PATH主要用于指定查找共享库(动态链接库)时的路径,通过修改LD_LIBRARY_PATH,可以将共享库文件的搜索路径改为一个包含恶意代码的路径,从而在程序运行时执行这些恶意代码。

所以,Set-Uid程序在运行时的链接器或加载器会忽略LD_LIBRARY_PATH。

Task 6: The PATH Environment Variable and Set-UID Programs

创建代码文件task6.c:

捕获

编译并运行task6:

2.1

2.1

task6打印出当前目录下的所有文件。

查看task6的权限:

2.1

task6拥有普通用户seed的权限。

将task6变为Set-Uid程序:

2.1

在当前目录创建恶意代码bcode.c:

捕获2

恶意代码会运行一个新的shell。

PATH指定命令的搜索路径,更改环境变量PATH为当前目录,程序会先在当前目录寻找(找到恶意程序)。

编译bcode.c为ls,再次执行task6:

1.1

成功执行恶意程序,但shell并不是用root权限运行的。

这是因为,system()首先执行/bin/sh程序,在Ubuntu20.04(以及之前的几个版本)中,/bin/sh实际上是一个指向/bin/dash的符号链接。这个shell程序有一个对策,可以防止自己在Set-UID进程中被执行: 如果dash检测到它是在Set-UID进程中执行的,它会立即将有效用户ID更改为进程的真实用户ID,放弃特权。

将/bin/sh链接到/bin/zsh,再执行task6:

5.1

shell以root权限运行。

Task 7: The LD_PRELOAD Environment Variable and Set-UID Programs

创建代码mylib.c(里面有名为sleep的函数):

2.2

编译mylib.c,生成一个名为libmylib.so.1.0.1的共享库,并链接C标准库.

1.1

创建代码myprog.c(其中使用sleep函数):

2.1

修改环境变量LD_PRELOAD为当前目录下我们自己创建的共享库,在普通用户seed下执行myprog:

1.2

将myprog设置成Set-Uid程序,再执行:

1.3

sleep一秒后结束程序。

在root用户下修改环境变量LD_PRELOAD,并运行myprog:

1.4

退出root用户,在普通用户seed下再运行myprog:

1.5

sleep一秒后结束程序。

创建一个新的普通用户user1,将myprog设置为Set-UID user1程序:

1.6

sleep一秒后结束程序。

猜想原因:myprog一般会继承环境变量,但动态连接器有保护机制,在一些情况下会防止LD_PRELOAD被改变。

解释现象:

  1. 创建验证代码test.c:

3.1

3.2

代码打印子进程环境变量。

修改环境变量:

3.7

编译执行test.c,将环境变量存进child_1.txt:

3.4

更改test.c,打印父进程环境变量:

3.3

编译执行test.c,将环境变量存进parent_1.txt:

3.4

比较child_1.txt, parent_1.txt,没有不同。

3.53.6

父进程和子进程的LD_PRELOAD都是./libmylib.so.1.0.1

所以,子/父进程都继承了修改的环境变量。

  1. test.c:打印子进程环境变量

4.1

将test设置为Set-Uid程序,将打印结果存入child_2.txt

4.1

test.c:打印父进程环境变量

test是普通权限文件,打印结果存入parent_2.txt,比较child_2.txt和parent_2.txt,parent_2.txt中多出LD_PRELOAD.

所以,父进程(普通程序)继承了修改的环境变量,子进程(特权程序)没有。

  1. 进入root用户,修改环境变量,打印子/父进程的环境变量

4.2

比较环境变量,相同,查看txt,子/父进程的环境变量中都有被修改的LD_PRELOAD。

4.34.4

所以,在root用户下运行,父进程和子进程都能继承修改的环境变量。

在seed用户下运行,子进程不能继承。

  1. 修改环境变量,在seed用户下打印子进程(用户user1的Set-Uid程序)和父进程(用户seed的普通程序)的环境变量。

5.15.2

比较它们的环境变量,父进程继承了改变的环境变量,子进程没有。

总结:当运行进程的真实用户ID与程序的拥有者的用户ID不一致时,进程会忽略掉父进程的LD_PRELOAD环境变量。

Task 8: Invoking External Programs Using system() versus execve()

创建代码catall.c:

捕获

编译代码,设置为Set-Uid程序,执行:

6.1

修改使/bin/sh指向zsh:

6.2

执行catall “aa;/bin/sh”,它实际上执行了两个命令,“/bin/cat/aa”和”/bin/sh”,catall这个特权程序使用shell执行了/bin/sh的命令,用它的root权限运行了一个shell。

通过这个shell就可以执行一些原来不能做的命令。

改变代码,使用execve():

捕获

重复上次的操作:

捕获

没有生成特权shell。

system()对于数据和代码没有明确的区分,但execve()明确地要求将输入分成代码(第一个参数)和数据(第二个和第三个参数),因此数据输入无法变成代码。

Task 9: Capability Leaking

在root下创建一个etc文件夹,文件夹内创建zzz文件,并设置其权限为0644:

1.2

zzz是只读的没有写入任何内容的文件:

1.3

创建代码cap_leak.c:

捕获

代码尝试以root用户权限打开文件zzz并写入一些数据,然后永久放弃root权限,最后关闭文件。

编译执行代码并将程序设置为特权程序:

2.1

查看zzz,已经写入数据:

2.2

运行Set-UID程序时,进程会暂时获得root权限,这时打开zzz文件,就会获得root权限下的读写文件、向文件中添加内容的权限,即使后面使用setuid()释放了root权限,但没有释放的进程已经获得的特权功能。

标签:bin,set,uid,程序,Set,进程,root,环境变量
From: https://www.cnblogs.com/wxrwajiez/p/18516118

相关文章

  • IOError: [Errno 2] No such file or directory: '/tmp/pip-build-TOULQc/urllib3/set
     [root@]#pipinstallelasticsearch==6.8.2Collectingelasticsearch==6.8.2Downloadinghttp://mirrors.cloud.aliyuncs.com/pypi/packages/96/7a/3627579d85bd4d9f4bf73b1d4240e11612f02d86c7c53fbb934cd11d5d57/elasticsearch-6.8.2-py2.py3-none-any.whl(90kB)......
  • 【一分钟配置Python环境变量
    配置Python环境变量可以帮助系统找到Python解释器和相关工具。下面是如何在不同操作系统上配置Python环境变量的步骤:Windows 1.安装Python:在官方网站下载并安装Python,安装过程中选择“AddPythontoPATH”选项。手动配置环境变量:右击“此电脑”或“计算机”,选择“属性......
  • redis详细教程(3.ZSet,Bitmap,HyperLogLog)
    ZSetRedis的ZSet(有序集合)是一种特殊的数据类型,它允许存储一系列不重复的字符串元素,并为每个元素关联一个分数(score)。这个分数用于对集合中的元素进行排序。ZSet的特点是:唯一性:集合中的每个元素都是唯一的。可排序性:元素可以根据分数进行排序。内部实现:ZSet的内部实现......
  • latex workshop在vscode中的settings.json设置
    //latex"latex-workshop.latex.autoBuild.run":"never","latex-workshop.showContextMenu":true,"latex-workshop.intellisense.package.enabled":true,"latex-workshop.message.error.show":fals......
  • 从 GC 到 WeakMap、WeakSet
    一、内存泄漏1.1简介内存泄漏:指计算机科学中的一种资源泄漏,主要是因为计算机程序内存管理疏忽或错误造成程序未能释放已经不再使用的内存,因而失去对一段已分配内存空间的控制,程序将继续占用已不再使用的内存空间,或是存储器所存储的对象,无法通过执......
  • 易优cms系统报错unserialize(): Error at offset 0 of 1571 bytes_Eyoucms系统报错问
    解决方案清除缓存通过FTP访问服务器。导航至 /data/runtime 目录。删除该目录下的所有文件和文件夹。升级系统登录后台。检查是否有可用的更新。升级到最新版本,以确保已知的问题已被修复。检查代码如果问题仍然存在,可以检查 \corelibrary\think\cache\dri......
  • 数据结构————map,set详解
    今天带来map和set的详解,保证大家分清楚一,概念map和set是一种专门用来搜索的容器或数据结构map能存储两个数据类型,我们称之为<key-value>模型set只能存储一个数据类型,我们称之为纯<key>模型它们的效率都非常非常高,我们来一个一个了解。二,详解map1,map的说明map是一个接......
  • P9131 [USACO23FEB] Problem Setting P 题解
    P9131[USACO23FEB]ProblemSettingP题解注意到最终形成的困难序列是一个不断包含的子集的关系,包含是非严格单调的,考虑转化为单调的形式易于计数dp。具体地,对于一些相同的困难值\(i\),算出其内部排列数\(g(i)\),于是转化成了单调的dp形式。于是实际上计算\(dp_{i}\)表示......
  • Setting up a mobile hotspot on your Samsung Galaxy phone is straightforward
    SettingupamobilehotspotonyourSamsungGalaxyphoneisstraightforward.Herearethesteps:OpenSettings:Swipedownfromthetopofthescreentoopenthenotificationshade,thentapthegearicontoaccessSettings.Connections:TaponConnec......
  • 点云学习笔记4——点云滤波降采样后进行4PCS粗配准【四点一致集配准算法(4-Point Congr
    #include<iostream>#include<pcl/point_cloud.h>#include<pcl/point_types.h>#include<pcl/filters/voxel_grid.h>#include<pcl/common/common_headers.h>#include<pcl/io/pcd_io.h>#include<pcl/visualization/cloud_vi......