0x1.GWDB-2022-0012-施耐德电气IGSS堆越界写漏洞
1 打开提供的环境

2 启动IGSS

2 nmap扫描确认从外部能访问服务

使用-Pn和-p-进行全端口不用ping的扫描
3 在虚拟机内确认当前服务的pid

4 运行漏洞利用脚本并检查服务
python ./igss_dataserver_heap_overwrite.py -t 192.168.122.195 -p 12401 -v


5 漏洞分析
https://www.tenable.com/security/research/tra-2022-22
根据漏洞报告找到漏洞点
捋顺程序流
先来找一下程序的主函数
这个程序要从网络上收发消息,肯定会创建线程
通过_beginthreadex的引用,找到函数
逐一查看发现最像服务启动的函数
追踪sub_4b2140
发现这是一个循环监听socket的函数,当有连接时会进入sub_4b2750
ai是这么说的

sub_4b43f0如下
进入sub_4b4460查看
最后return处调用了sub_4b4740,进入查看
其中调用sub_4b3090
进入发现接收消息的函数,也是存在漏洞的关键函数
接下来逆向数据结构
还原消息结构


向前溯源,找到数据结构的最大大小0x2080
结合ai分析出大概的数据结构
根据漏洞报告,可知此处opcode为1时存在堆溢出漏洞
当首次连接的opcode为1时,会将handle_ptr赋值,确定vtable。

在一次连接中,当第一次消息的第十四、十五、十六和十七个字节不为0时,则会继续接收消息
此处可查看一下opcode为1时,vtable+2所指向的函数的返回值

返回值为1,返回后下一次循环直接进入case 1
进入vtable + 3
结合ai分析出返回值大致含义
下一次进入case 4
分析后会发现,case 4毫无价值,会直接进入case 5,然后goto label_126然后进入case 6然后将handle删掉,重新等待消息,这与漏洞报告不符。
注意到此处
当Src+14处为0时,进入case 5,case5会使函数返回,但返回后会重新执行该函数,但此时handle存在值,且pad_04在case5时被置为0,所以下一次会执行vtable_1
逆向一下vtable_1的数据结构后得到
结合opcode=1时的初始化函数
发现在vtable_1中memcpy的起始地址是由第一次发包时包内的size参数决定的,而如果第一次发包中的size*12不等于包的长度,则会使第二次包的内容合并的位置在第一次包的内容的后面位置,而不是刚好接在后面,从而发生溢出
如图,第二个包中的B没有接在A的后面,而是空了一段距离。
编写payload测试
1 | from pwn import * |
