Skip to content

integer overflow in dwgutil.cpp #2

@jinyu00

Description

@jinyu00

The vulnerability lie in dwgutil.cpp

void dwgCompressor::decompress18(duint8 *cbuf, duint8 *dbuf, duint32 csize, duint32 dsize){//对一个缓冲区的数据进行解压

...............................................................
...............................................................
...............................................................

        // The vulnerability Point !!!!!!!!
        //when  rpos < compOffset , j could be a large value.
        for (duint32 i=0, j= rpos - compOffset -1; i < compBytes; i++) { // 出现 rpos < compOffset, 会出现负数,越界读
            bufD[rpos++] = bufD[j++];
        }
...............................................................
...............................................................

As you can see , j's type is duint32 ( unsigned int ). when rpos < compOffset , j could be a negative number . Because j is unsigned , j will be a large value (:like 0xffffffff)

Let see in gdb

----------------------------------registers-----------------------------------]
RAX: 0xa98 
RBX: 0x7fffffffd9a0 --> 0x793330 --> 0xbab937a8292b0800 
RCX: 0xa ('\n')
RDX: 0x325 
RSI: 0x326 
RDI: 0x7fffffffd9a0 --> 0x793330 --> 0xbab937a8292b0800 
RBP: 0x2d36 ('6-')
RSP: 0x7fffffffd7c0 --> 0x7 
RIP: 0x4a1817 (<dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+455>:	not    ebp)
R8 : 0x793330 --> 0xbab937a8292b0800 
R9 : 0x1c 
R10: 0x15b0 
R11: 0x0 
R12: 0x0 
R13: 0x6968 ('hi')
R14: 0x7401 
R15: 0x857
EFLAGS: 0x283 (CARRY parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x4a180b <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+443>:	sub    r13d,r12d
   0x4a180e <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+446>:	cmp    ecx,r13d
   0x4a1811 <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+449>:	ja     0x4a19eb <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+923>
=> 0x4a1817 <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+455>:	not    ebp
   0x4a1819 <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+457>:	add    ebp,eax
   0x4a181b <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+459>:	test   ecx,ecx
   0x4a181d <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+461>:	lea    edi,[rbp+rcx*1+0x0]
   0x4a1821 <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+465>:	jne    0x4a182d <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+477>

Breakpoint 3, 0x00000000004a1817 in dwgCompressor::decompress18 (this=this@entry=0x7fffffffd9a0, cbuf=cbuf@entry=0x793330 "", dbuf=dbuf@entry=0x7b2e30 "+)\250\067\271\272\031\030\030\230(97\270\032\034\214", csize=csize@entry=0x857, dsize=dsize@entry=0x7400)
    at intern/dwgutil.cpp:204
204	        if (remaining < compBytes){
gdb-peda$ 

eax is rpos and ebp is compOffset , you can see rpos(0xa98) < compOffset (0x2d36). then j could be 0xffffdd61 , crash !!!!!

[-------------------------------------code-------------------------------------]
   0x4a1831 <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+481>:	lea    ecx,[rax+0x1]
   0x4a1834 <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+484>:	mov    DWORD PTR [rbx+0x1c],ecx
   0x4a1837 <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+487>:	lea    ecx,[rbp+0x1]
=> 0x4a183a <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+490>:	movzx  esi,BYTE PTR [rdx+rbp*1]
   0x4a183e <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+494>:	cmp    ecx,edi
   0x4a1840 <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+496>:	mov    BYTE PTR [rdx+rax*1],sil
   0x4a1844 <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+500>:	jne    0x4a1828 <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+472>
   0x4a1846 <dwgCompressor::decompress18(unsigned char*, unsigned char*, unsigned int, unsigned int)+502>:	xor    ecx,ecx
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffd7c0 --> 0x7 
0008| 0x7fffffffd7c8 --> 0xaf7b8da0e 
0016| 0x7fffffffd7d0 --> 0x4e300d --> 0xa736574796220 (' bytes\n')
0024| 0x7fffffffd7d8 --> 0x7fffffffd970 --> 0x78e7e8 --> 0xa73657479000a ('\n')
0032| 0x7fffffffd7e0 --> 0x78e7e8 --> 0xa73657479000a ('\n')
0040| 0x7fffffffd7e8 --> 0x47edb8 (<DRW_dbg::print(std::string)+40>:	mov    rax,QWORD PTR [rsp+0x10])
0048| 0x7fffffffd7f0 --> 0x0 
0056| 0x7fffffffd7f8 --> 0x7fffffffd9e0 --> 0x78f7e0 --> 0x7fff00000001 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions