[하루한줄] heap out-of-bounds write in Telegrams animated stickers

URL

Hunting for bugs in Telegram’s animated stickers remote attack surface

Target

  • 텔레그램 안드로이드 v7.1.0(2090) (2020년 9월 30일 릴리스) 이전 버전
  • 텔레그램 iOS v7.1 (2020년 9월 30일 릴리스) 이전 버전
  • 텔레그램 macOS v7.1 (2020년 10월 2일 릴리스) 이전 버전

Explain

텔레그램 비밀 채팅 애니메이션 스티커 기능에서 remote code execution이 가능한 취약점이 발견되었습니다. 텔레그램은 애니메이션 스티커를 렌더링 하기 위해서 rlottie를 수정하여 사용합니다.

취약점은 VGradientCache::generateGradientColorTable에 존재하며, 반복문의 범위 검증 미흡으로 heap memory out-of-bound write이 발생합니다.

bool VGradientCache::generateGradientColorTable(const VGradientStops &stops,
                                                float                 opacity,
                                                uint32_t *colorTable, int size)
{
    int                  dist, idist, pos = 0, i;
    bool                 alpha = false;
    int                  stopCount = stops.size();
    const VGradientStop *curr, *next, *start;
    uint32_t             curColor, nextColor;
    float                delta, t, incr, fpos;

    if (!vCompare(opacity, 1.0f)) alpha = true;

    start = stops.data();
    curr = start;
    if (!curr->second.isOpaque()) alpha = true;
    curColor = curr->second.premulARGB(opacity);  // out-of-bounds value, curr->second is controlled
    incr = 1.0 / (float)size;                     // static
    fpos = 1.5 * incr;                            // static

    colorTable[pos++] = curColor;

    while (fpos <= curr->first) {                 // curr->first is controlled and pos is not checked to be < size, leading to 
        colorTable[pos] = colorTable[pos - 1];    // out-of-bounds write
        pos++;
        fpos += incr;
    }
    [...]

size, fpos, incr는 static value이고, curr->first, curr->second는 애니메이션 스티커에서 값을 직접 받아옵니다. 반복문에서 colorTable을 할당할 때 poscolorTable 배열 크기인 size 간의 검사를 하지 않아 애니메이션 스티커의 curr->first 값에 따라 힙 메모리 arbitrary overwrite가 가능합니다.

스티커를 통해 overwrite 된 값은 premulARGB()getColorReplacement()를 통해 인코딩 되고, 해당 함수들의 소스 코드를 확인할 수 있으므로 해커가 조작할 수 있으며, ASLR 우회 가젯이 존재하면 Remote Code Execution이 가능합니다.

해당 취약점은 사용자가 보낸 sticker.id가 텔레그램 클라우드의 public sticker set에 존재하는지 확인하여 임의로 조작된 스티커 파일을 전송할 수 없는 방법으로 패치되었습니다.