sandyre/libopencad

heap buffer overflow in CADFile::ReadTables

hac425xxx opened this issue · 0 comments

crash context

pwndbg> r
Starting program: /home/xxx/workplace/asan/libopencad/build/cadinfo_debug heapoverflow-2-opencad.dwg

Program received signal SIGSEGV, Segmentation fault.
0x00000000004c2788 in Read2B (pabyInput=0x7035e0 "D5D\\\304\061\001Q\251DiDeD>\035*", nBitOffsetFromStart=@0x7fffffffc868: 9166815975) at /home/xxx/workplace/asan/libopencad/lib/dwg/io.cpp:58
58      memcpy( a2BBytes, p2BByte, 2 );
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────[ REGISTERS ]────────────────────────────────────────────────────────────────────────────────
 RAX  0x44bc863c
 RBX  0x478102 ◂— push   rbp
 RCX  0x1
 RDX  0x7035e0 ◂— 0x510131c45c443544
 RDI  0x7035e0 ◂— 0x510131c45c443544
 RSI  0x7fffffffc868 ◂— 0x2226282e7
 R8   0x703280 ◂— 0xe821b93232b637a4
 R9   0x0
 R10  0x7fffffffc560 —▸ 0x703080 ◂— 0x91d19e49120400a0
 R11  0x7ffff737c310 ◂— jle    0x7ffff737c2bc
 R12  0x4737a0 (_start) ◂— xor    ebp, ebp
 R13  0x7fffffffe100 ◂— 0x2
 R14  0x0
 R15  0x0
 RBP  0x7fffffffc820 —▸ 0x7fffffffdaa0 —▸ 0x7fffffffdc10 —▸ 0x7fffffffdc60 —▸ 0x7fffffffdc90 ◂— ...
 RSP  0x7fffffffc820 —▸ 0x7fffffffdaa0 —▸ 0x7fffffffdc10 —▸ 0x7fffffffdc60 —▸ 0x7fffffffdc90 ◂— ...
 RIP  0x4c2788 ◂— movzx  eax, word ptr [rax]
─────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────
 ► 0x4c2788    movzx  eax, word ptr [rax]
   0x4c278b    mov    word ptr [rbp - 0x20], ax
   0x4c278f    mov    rax, qword ptr [rbp - 0x10]
   0x4c2793    cmp    rax, 7
   0x4c2797    jne    0x4c27b1
    ↓
   0x4c27b1    movzx  eax, byte ptr [rbp - 0x20]
   0x4c27b5    movzx  edx, al
   0x4c27b8    mov    rax, qword ptr [rbp - 0x10]
   0x4c27bc    mov    ecx, 6
   0x4c27c1    sub    ecx, eax
   0x4c27c3    mov    eax, ecx
─────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]──────────────────────────────────────────────────────────────────────────────
In file: /home/xxx/workplace/asan/libopencad/lib/dwg/io.cpp
   53     size_t        nByteOffset      = nBitOffsetFromStart / 8;
   54     size_t        nBitOffsetInByte = nBitOffsetFromStart % 8;
   55 
   56     const char * p2BByte = pabyInput + nByteOffset;
   57     unsigned char a2BBytes[2];
 ► 58     memcpy( a2BBytes, p2BByte, 2 );
   59 
   60     switch( nBitOffsetInByte )
   61     {
   62         case 7:
   63             result = ( a2BBytes[0] & binary(00000001) ) << 1;
─────────────────────────────────────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────────────────────────────────────────
00:0000│ rbp rsp  0x7fffffffc820 —▸ 0x7fffffffdaa0 —▸ 0x7fffffffdc10 —▸ 0x7fffffffdc60 —▸ 0x7fffffffdc90 ◂— ...
01:0008│          0x7fffffffc828 —▸ 0x4a61dd ◂— mov    byte ptr [rbp - 0x1130], al
02:0010│          0x7fffffffc830 —▸ 0x7fffffffcacf ◂— 0xec0e332900
03:0018│          0x7fffffffc838 ◂— 0x7f00ffffc809
04:0020│          0x7fffffffc840 ◂— 0x1f
05:0028│          0x7fffffffc848 —▸ 0x6f6a90 —▸ 0x6f0d30 —▸ 0x4b5ff6 (DWGFileR2000::~DWGFileR2000()) ◂— push   rbp
06:0030│          0x7fffffffc850 ◂— 0x117fffffffcaf0
07:0038│          0x7fffffffc858 ◂— 0x354400000100
───────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]────────────────────────────────────────────────────────────────────────────────
 ► f 0           4c2788
   f 1           4a61dd
   f 2           47e63c
   f 3           47e1b2
   f 4           476469 CADFile::ReadTables(CADFile::OpenOptions)+43
   f 5           476429
   f 6           475ead
   f 7           47604d
   f 8           473bf9 main+610
   f 9     7ffff7212f45 __libc_start_main+245
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Program received signal SIGSEGV (fault address 0x44bc863c)
pwndbg> 

program crash because p2BByte is inaccessible.

 const char * p2BByte = pabyInput + nByteOffset;
 unsigned char a2BBytes[2];
 memcpy( a2BBytes, p2BByte, 2 );

the pabyInput is a heap buffer which contain the content of our input dwg file and nByteOffset is too large.

pwndbg> p/x nByteOffset
$2 = 0x444c505c
pwndbg> 

This lead to heap buffer overflow

The poc

https://github.com/hac425xxx/fuzzdata/blob/master/heapoverflow-2-opencad.dwg