吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

搜索
查看: 1074|回复: 6

[漏洞分析] vxworks5.5里面rpcbind漏洞分析-3-整数溢出触发RCE

[复制链接]
LovenSar 发表于 2020-6-28 22:57

废话

前面两篇都是针对vxworks5.5的RPC/111里面的UDP进行分析。
这一篇主要根据进一步的分析来达到一个UDP包让vxworks“合法重启”的目的。
前两篇多少发现有点问题,请发现有问题的老师斧正,多谢。
vxworks5.5里面rpcbind漏洞分析-1
vxworks5.5里面rpcbind漏洞分析-2

这一篇里面多少有点废话,但是不影响后面的达成。
先给出重启脚本,针对vxworks5.5.1的,111端口开放的系统。
测试环境Vmware

payload反序列化

思路整理

对于payload

试了边界条件,8000 0000【对应最小的数值】和0000 000-7FFF FFFF【最大数值】不会发生溢出,那么也就是8000 0001-FFFF FFFF会溢出。不知道为啥8000 0000不会,因为那是负数,可能是因为是边界吧,有一些特殊的判定。

今天就来解析一下。

按照这个思路,继续下去。
可以先将数据分段

cc6ff7e2  #call ID
00000000  #student 1
00000002  #student 2
0001a086  #student 3
00000004  #student……
00000004
88888888
00000011
00000011
00001111
11111111
11111111
111111

我们再重新整理一下思路,如果想要读懂这一块代码,就去查阅一下整个函数是干嘛。
Svcudp_recv(),手上没有更加详细的源码,找到这个。
http://en.verysource.com/code/24037282_1/svc_udp.c.html

确定payload缓冲区

第一个参数是xprt,第二个是msg
xprt = svcudp_create(sock);
再找到到svcudp_create()

对于这个svcudp_bufcreate()可以查阅到资料

svcudp_bufcreate(sock, sendsz, recvsz)

所以,到这里我们可以暂时不用向上追溯。

回过头来,xprt就是一个接收套接字,内存里面重新开拓了一块空间。

接下来可以看看就是是svcudp_recv里面的xdr_callmsg()函数

我们重新整理一下思路,就是对于xdr_callmsg()函数的变量情况

先在xdr_callmsg函数前面F2下好断点,然后跟随步骤向下面进行跟随,

这里的arg_0是第一个参数,那么对于第一个参数我们该怎么确定是什么东西呢?

回到上一层的svcudp_recv函数里面,可以看到最后一个入栈的寄存器是edi

那就看看edi的来源,选中edi可以一直向前面追溯,到底从哪些地方拿了参数过来,沿着互相参数的传递,如果可以向上文追溯到我们已经知道的一些情况,那就可以停止了,因为知道它是什么东西。

在这里面可以看到,也是作为上一个函数的第一个参数但是edi没有被赋值,再向上也是被作为源操作数,说明可能代表的是一个特殊的引用,极有可能是svcudp_recv的参数。

继续向上找,可以看到有有趣的东西了。


在这里可以看到edi是被加减过,但是大体上edi也都是在一个地址区间里面,edi的最先来自eax,而eax来自第一个变量。

而我们前文已经提到了

svcudp_recv(xprt, msg)

xprt = svcudp_create(sock);

来自在内存中已经载入的套接字,这十分有趣了。

同样的我们也可以用同样的方法去知道其他参数的来源,但是我在这里就不详细讲了。

回到xdr_callmsg,就可赶上海航的进度了。

跟着程序往下走,可以看到走到这里。

对数据长度敏感的朋友都会知道long可能对应着一个长整型,所以,这里值得关注,同样这里的v24被反复调用,跳到我们的内存里面,然后按三下d编程长整型,我们双击发现了惊喜!

不知道的小伙伴,不知道这个地址是啥的话,再双击一下就会知道,这个就是recvfrom接收套接字的缓冲区

所以,这里我们就可以继续下去了。

这时候我们就要回过头去找到这个资料:

也就是说,这个是二进制的序列化,所以我们可以根据它取出来的赋值然后知道在干吗。

看刚刚的反汇编代码,数了一下,知道会有12个长整型,这一段程序也就是反序列化的解码工作。

分段解读

我们一个一个来解析

首先明确一下,a2肯定是一个反序列化工作完成之后需要返回的一个结构体,这个结构体暂时还不知道是什么。

第一个:

*a2 = ixdr_get_long(&v24);

可以知道,这个肯定是一个函数调用。

因为它直接作为指针,就像是跟海航说的call ID。

第二个;

如果为0直接退出了,啥没有。而且在recvfrom里面有

直接啥都没有。

跟海航的测试结果一样。

第三个:

必须为2

否则退出,跟海航的测试结果一样

第四个~第七个:

嘛事没有,可能是第一个函数调用的参数。

后面在分析一下也行。

接下来就比较有意思了:

Vxworks先取第九个参数,跳过了第八个参数:

如果第九个参数为0,那么第八个参数也没什么用。

这个函数的作用:分配不大于400个字节内存的地址赋值给第八个参数。所以我们也可以知道这个第八个参数也是一个指针,第九个参数的意思是长度。

已知a2是一个结构体,在v20被赋值那一句,

(a1[1] + 32))这个函数通过跳转,可以看到是这个函数

结合我们的payload,第九个参数以及之后的是这一段

00001111

11111111

11111111

111111

首先是执行(a2[8] + 3) & 0xFFFFFFFC,最后一行与出来作为第二个参数,其实说来也就是,这些位是不是1,是1的话,就作为参数【具体为啥这么整我也不知道】F-1111,C-1100

反正v20不为空的情况下,就将后面的这一堆1拷贝到刚刚第八个参数,那个指针指向的空间里面。

这个是结构体里面的东西,就是那个a2它已经将其反序列化完成了,对比一下

【后面分析的时候不小心把其中00000004给漏掉了,但是不影响程序的分析。】

继续分析xdr_callmsg剩下的程序流程。

接下来,又有一个bcopy,当然那个v24也是指向一个新的内存空间。

然后先取第十个和第十二参数。

但是我们知道这时候是没有的。那会出现什么问题呢?

我们可以观察一下这个a2

似乎没有见到a[10],双击进去可以看到是EEEE垃圾数据

然后程序运行到这里,自然是返回1,xdr_callmsg函数调用结束。

回到svcudp_recv()函数,那么我们再仔细分析它这个调用关系。

由最后的sendto我们可以得知

所以最后发送什么我们就不用管了,反正最后是怎么回事,就是在cache_get()之前出事了。

修改payload触发RCE

前面已经分析到了传递参数的问题,但是其实这并不直接影响payload发挥作用,其中我们比较关键的是如何改变payload来让vxworks发生我们所期望的。

先给出payload。我们这次有所改变。

'0000c35B000000000000000200000000876543210000000580000019'

所以我们直接回过头来,先看报错信息。

发现了这时候的PC其中就是payload的一部分。我们再改变一下试试看。

‘0000c35B000000000000000200000000123456780000000580000019’

说明这一段其实就是可以直接控制EIP了。所以我们只需要找到相对应的函数偏移地址,就可以劫持程序流了。所以我们可以先让vxworks重启试一下。

但是,这里需要注意以下几点:

  • vxworks没有地址随机化。

  • vxworks是裁剪式系统,也就是说,对于不同的工程,生成的vxworks文件相同的一个函数的偏移不固定。

  • vxworks5.5其实偏移量是固定的0x00308000,也就是说vxworks装在镜像相对于内存的偏移量是固定的。

基于以上三点,我们需要处理好的问题就是找到一个相对稳定的函数。

尝试了几个函数,最终这个函数是最稳定的,将其填充到相应位置。最终的payload是

0000c35B000000000000000200000000003081680000000580000019

让我们单步调试一下。

这里是一个整数溢出的漏洞,只需要将其添上负数,也就是最高位为1,其他的随便整,就可以跳到我们想要的地方去。

我们知道对于之前的payload,发生错误的对应位置是上面那个断点处。

让我们深入一下就可以知道,跳转到svcauthsw那里,可以看到是类似跳表之类的,×4的操作可以确定都是四个字节的,关键是哪一个函数可以为我们所用

往下翻了之后发现了一个叫做svcudp_getargs的函数。

其相对于svcauthsw的位移为25,对应19H。

在关键处call edx那里我们可以看见,此时edx指向一个不知道是什么性质的内存块【估计是堆块】

继续F7跟进一下,可以看到跳到了这里


可以看到,pop ebx; retn; 对应的机器码是0000C35B

当我们继续单步调试看看

就可以看到了EIP变成了我们payload里面对应的地址,reboot。

F9释放IDA,就可以看见vxworks重启了。

既然可以拿到我们想要的信息,那么我们可以进一步取得我们想要的结果呢?

当然之前说的那三点都是不能忽略的。

第一步RCE我们已经达成。
接下来是堆喷射。
有空再试一下,没了解过什么是堆喷射。

免费评分

参与人数 5威望 +2 吾爱币 +104 热心值 +5 收起 理由
不谙世事的骚年 + 1 + 1 我很赞同!
woyucheng + 1 + 1 谢谢@Thanks!
22222 + 1 + 1 热心回复!
willJ + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
dreamlivemeng + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

majia4075669072 发表于 2020-6-29 00:08
给楼主点赞,现在用VxWorks的不多了吧,以前电信行业用的多,现在都被Linux取代了。
两个人的地球 发表于 2020-6-29 08:50
 楼主| LovenSar 发表于 2020-6-29 12:12
majia4075669072 发表于 2020-6-29 00:08
给楼主点赞,现在用VxWorks的不多了吧,以前电信行业用的多,现在都被Linux取代了。

好的,我目前也是在学习的路上,谢谢分享
andrelxj 发表于 2020-7-1 11:29
太棒了,支持楼主发贴!!!!!!!
jnez112358 发表于 2020-7-1 17:54
支持呀,谢,继续学习
chenjingyes 发表于 2020-7-1 23:36
VxWorks工控行业用得多,是篇很好的参考文章
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2020-7-2 16:26

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表