这篇文章发表于 1515 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
本文主要是对最近一次作业的简单记录。
shell变量,又称本地变量,包括私有变量以及用户变量(也就是环境变量),shell变量仅在本shell中起作用;环境变量,又称用户变量,与shell无关。简而言之,shell变量包含了环境变量,而环境变量的作用域大于shell变量。shell变量可直接用set
来查看,而环境变量可直接用env
来查看。
1 | seed@VM:~$ echo $PATH |
或者使用export
命令也可。
修改PATH环境变量一般直接export PATH="...."
,或者直接写在/etc/profile
中,利用source命令来使用(source命令也可以写于.bashrc
这类文件中)。
常用在环境变量劫持和rbash中。
特殊权限SUID
当 s 出现在文件拥有者的 x 权限上时称为SUID,也称SETUID。
设置相关权限:
1 | #设置前: -rwxrwxr-x |
因为相关的程序在运行时会拥有root权限,这个常用于Linux提权。 相关查询命令: find / -user root -perm -4000 2>/dev/null
相关网站与好文章:
https://www.secshi.com/29335.html
https://www.drdobbs.com/dangers-of-suid-shell-scripts/199101190
http://www.cis.syr.edu/~wedu/Teaching/cis643/LectureNotes_New/Set_UID.pdf
特殊权限SGID
当 s 标志出现在用户组的 x 权限时称为 SGID。
设置相关权限:
1 | sudo chmod g+s exec |
相关查询命令: find / -perm -g=s -type f 2>/dev/null
特殊权限SBIT
当s/t标志出现在目录其他用户的x权限上时称为SBIT。SBIT 对目录的作用是:当用户在该目录下创建新文件或目录时,仅有自己和 root 才有权力删除。
设置相关权限:
1 | sudo chmod o+t exec |
export命令
命令export PATH=.:$PATH
就是将当前位置归入PATH
中,这个命令存在着一定风险,事实上结合软链接它有可能完成劫持,比如:
1 | ln -s /bin/bash ls |
请注意这个命令和命令export PATH=$(pwd):$PATH
存在着区别。
接下来聊一聊这些权限与Linux提权。这里额外提供了三个基本操作。
一 | 滥设权限
这部分和使用SUID提权没有多少关系,放在这里纯粹是为后面做一些铺垫。
比如说某些人修改了/etc/passwd
的权限(或者是由于umask配置出错,可检查/etc/profile
),让上面的任何用户都能够读写。这里直接修改该文件即可完成后门用户的添加,根本不需要去修改/etc/shadow
文件。
1 | ###前期准备 |
二 | 利用SUID
1 | find / -user root -perm -4000 2>/dev/null |
因为较高版本Linux对真实UID和事实UID动了些手脚(导致更安全了……),如果启动bash时的Effective UID
与Real UID
不相同,而且没有使用-p
参数(当实际和有效的用户ID不匹配时打开,禁用$ENV
文件的处理和外壳程序的导入功能,关闭此选项将导致有效的uid和gid设置为实际的uid和gid),则bash会将Effective UID
还原成Real UID
。相关文章可参见《谈一谈Linux与suid提权》,其实dash也是类似的,需要加上-p
参数。
这里类似地,我们使用lua或是python3来完成写入root权限,注意,这里必须加上SETUID,否则系统的安全机制会导致提权失败。
1 | vim -c ':lua local file = io.open("/etc/passwd", "a");file:write("hacker:$1$salt$qJH7.N4xYta3aEG/dfqo/0:0:0:root:/root:/bin/bash\n");file:close()' |
可见目前的Linux环境比以前的版本安全多了,根据之前的理解,这里再编译一个具有SUID的程序来完成实验:
1 |
|
可以清楚地看到我们现在是root权限。
三 | 环境变量劫持
比如说我们要劫持这样的一个程序a:
1 |
|
怎么搞?
可以利用实验二中的程序,命名为ifconfig
,然后进行环境变量劫持,这里劫持是对相对路径的劫持。
1 | export PATH=/tmp:$PATH |
这个是为了权限的考虑。
其实没必要使用实验二中的程序,直接使用软链接即可完成攻击。
1 | ln -s /bin/bash ifconfig #rm ifconfig |
继续加大难度。如果写程序的人考虑到了相对路径带来的安全隐患,比如将文件修改成为了下面这样的具有SUID的程序b,我们又该怎么办呢?
1 |
|
这里的权限其实没有特别大的区别,关键是system
里面调用的命令被换了。
就可以尝试在变量LD_PRELOAD
上面做手脚,因为它出现在了env
的返回结果之中,并且可以为用户所控制,这里的侧重点在于用户该如何控制并影响程序的行为。经过思考与尝试后,个人感觉无法在seed环境下通过程序b
提权(在一些老旧的bash版本或是古老的Linux环境中有办法成功(或许特殊的条件竞争的情况也可能成功),详情参见此文章),因为sudo env
的返回结果和env
的返回结果大相径庭(这是因为高版本对suid的程序进行了check,环境变量用户也就不可控了),也就没办法劫持(除非root设置了LD_PRELOAD
路径,并且用户在该路径中可写),但是我能够改变未设置SUID的程序的行为。
一般来说,程序的链接分为静态链接和动态链接,静态链接就是把所有所引用到的函数或变量全部地编译到可执行文件中。动态链接则不会把函数编译到可执行文件中,而是在程序运行时动态地载入函数库,也就是运行链接。对于GCC而言,默认情况下,所编译的程序中对标准C函数的链接,都是通过动态链接方式来链接libc.so.6
这个函数库的。
这里借用该文章来编写一个hjack.c
的文件:
1 |
|
然后生成.so
文件准备劫持,指定export LD_PRELOAD="$(pwd)/hjack.so"
,可以使用ldd b
来查看其对应的加载顺序,可以使用unset LD_PRELOAD
来解除。
这里生成的程序不要设置SUID,可以先运行一下,能够得到如下结果——原本的ifconfig
的结果变成了反弹shell。
设置root所有和SUID之后重新运行,发现只会弹出正常的ifconfig
的内容。使用sudo ldd b
和ldd b
的结果不同,应该就是造成劫持失败的原因。然而缺乏权限,用户一般没办法修改。
另外和LD_PRELOAD
类似,还有 LD_AUDIt 和 LD_DEBUG_OUTPUT 也可以在历史版本的linux中能够做到提权。