12558网页游戏私服论坛

 找回密码
 立即注册
游戏开服表 申请开服
游戏名称 游戏描述 开服状态 游戏福利 运营商 游戏链接
攻城掠地-仿官 全新玩法,觉醒武将,觉醒技能 每周新区 经典复古版本,长久稳定 进入游戏
巅峰新版攻 攻城掠地公益服 攻城掠地SF 新兵种、新武将(兵种) 进入游戏
攻城掠地公 散人玩家的天堂 新开 进入游戏
改版攻城掠 上线即可国战PK 稳定新区 全新改版,功能强大 进入游戏
少年江山 高福利高爆率 刚开一秒 江湖水落潜蛟龙 进入游戏
太古封魔录 开服送10亿钻石 福利多多 不用充钱也可升级 进入游戏
神魔之道 签到送元宝 稳定开新区 送豪华签到奖励 进入游戏
神奇三国 统帅三军,招揽名将 免费玩新区 激情国战,征战四方 进入游戏
龙符 三日豪礼领到爽 天天开新区 助你征战无双 进入游戏
王者之师 免费领豪华奖励 免费玩新区 6元送6888元宝 进入游戏
查看: 169|回复: 0

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

[复制链接]
发表于 2020-6-30 22:56:54 | 显示全部楼层 |阅读模式
废话

前面两篇都是针对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 ID00000000  #student 100000002  #student 20001a086  #student 300000004  #student……00000004888888880000001100000011000011111111111111111111111111我们再重新整理一下思路,如果想要读懂这一块代码,就去查阅一下整个函数是干嘛。
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我们已经达成。
接下来是堆喷射。
有空再试一下,没了解过什么是堆喷射。

来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
楼主热帖
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|12558网页游戏私服论坛 |网站地图

GMT+8, 2024-5-19 01:00 , Processed in 0.134766 second(s), 31 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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