CVE-2013-2471漏洞分析

1、 漏洞成因

触发漏洞的代码:

poc代码首先构造一个恶意的DataBufferInt dst,缓冲区长度为4个int,但是却指定了14的初始化偏移,该偏移会在写操作中进行有效性验证。

为绕过验证,poc定义了恶意的类MySampleModel,重载了SinglePixelPackedSampleModel类的getNumDataElements方法,使其返回0。

与原始方法的对比:

当调用Raster.createWritableRaster创建WritableRaster wr2时:

最终调用IntegerInterleavedRaster构造方法构造恶意的WritableRaster:

其中的this.numDataElems = sppsm.getNumDataElements();因方法被重载过,numDataElems被初始化为0,之后调用verify()进行有效性检查,该方法在父类IntegerComponentRaster中实现:

 

numDataElements字段等于0,可以绕过dataOffsets[]的检查,最后生成的WritableRaster对象拥有恶意的偏移14,却被JVM认为是合法的。

最后调用cc.compose(wr1, wr2, wr2)实现了内存拷贝,DataBufferInt src中的数据突破内存访问限制,被拷贝到int a[]对象的内存区域中,将a.length字段覆盖为0xFFFFFFFF,从而突破a的内存访问限制,可以对任意内存进行读写。

执行cc.compose(wr1, wr2, wr2)之前的内存布局:

02B78818处为DataBufferInt dst对象,2B78840处为构造dst时传入的int[4]对象,02B78860处为dst中的dataOffsets[]对象,02B78880为紧接着dst定义的int a[16]对象。

调用cc.compose(wr1, wr2, wr2)之后的内存:

可以看到,02B78884处开始的8个字节被改写,也就是dst缓冲区的偏移14的位置,02B78888处为a.length字段,被改写为0xFFFFFFFF,接下来可以利用int a[]对象任意访问内存,利用该漏洞。

2、 漏洞利用

首先紧接着int a[]分配一个Object数组,oo[2]为System.setSecurityManager(null)的Statement,oo[3]为具有AllPermission权限的AccessControlContext,oo[4]保存oo[2]的target字段:

 

内存布局为:

02B70DC8为Object oo[]数组,紧接着int a[]存放。02B70DE0是具有AllPermission权限的acc,02B70DF8为oo[2]的AccessControlContext字段,02B70DFC为oo[2]的target字段。

利用int a[]搜索并替换oo[2]的acc:

 

oo[2]的acc已被替换为具有完整权限的acc,即oo[3]中保存的acc:

oo[2]现在已经具有完整的权限,调用((Statement)oo[2]).execute()来执行System.setSecurityManager(null),不会触发异常,完成漏洞的利用。

POC出自 http://packetstormsecurity.com/files/122806/

[via@南京瀚海源]