CVE-2018-5996 7zip學(xué)習(xí)筆記

CVE-2018-5996 7zip學(xué)習(xí)筆記

前置知識(shí)

Range encoding

顧名思義,就是把一個(gè)字符串流根據(jù)字符出現(xiàn)的頻率,轉(zhuǎn)化成一個(gè)范圍(閾值)

https://en.wikipedia.org/wiki/Range_encoding

簡(jiǎn)介

原文
https://landave.io/2018/01/7-zip-multiple-memory-corruptions-via-rar-and-zip/#fn:2

可觸發(fā)堆溢出和棧溢出

PPMd是壓縮算法RAR3壓縮算法的實(shí)現(xiàn)

bug

對(duì)于每個(gè)RAR版本,最多創(chuàng)建一個(gè)coder。如果同一個(gè)版本有多個(gè)實(shí)例,就使用同一個(gè)coder。
調(diào)用code可能返回失敗S_FALSE,而且被創(chuàng)建的coder下次仍然會(huì)使用。我們找到一個(gè)能讓它返回
S_FALSE的函數(shù)。

CInBufferException,當(dāng)從輸入流中讀入時(shí),這個(gè)異??赡軙?huì)被拋出,我們可以用一個(gè)RAR3實(shí)例
來觸發(fā)這個(gè)異常,拋出S_FALSE

一旦RAR3在PPMd更新時(shí)拋出異常,會(huì)讓PPMd模型處于不穩(wěn)定狀態(tài),同樣的coder會(huì)被用作下個(gè)實(shí)例,
即使在CInBufferException已經(jīng)拋出S_FALSE的異常碼

RAR3解碼器維持PPMd模型的狀態(tài),PPMd模型只有在一個(gè)item顯示要求時(shí)才會(huì)重新初始化,
這意味著我們可以這樣做:

  • 當(dāng)PPMd模型在更新時(shí),構(gòu)造一個(gè)RAR3實(shí)例來觸發(fā)ClnBufferException,
  • 之后的item沒有重置,因此PPMd會(huì)處于不穩(wěn)定狀態(tài)

PPMd Preliminaries

PPMd壓縮算法是建立有限階D的馬爾科夫模型,模型狀態(tài)實(shí)質(zhì)是一個(gè)256元的上下文樹,最大深度為D。
從根到上下文節(jié)點(diǎn)的路徑將被解釋為字節(jié)符號(hào)序列,父關(guān)系將被理解為后綴關(guān)系。除此之外,每一個(gè)
上下文結(jié)點(diǎn)保存與后繼節(jié)點(diǎn)相關(guān)的后繼符號(hào)的統(tǒng)計(jì)頻率。

使用以下名為CPpmd7_Context的結(jié)構(gòu)體來表示一個(gè)上下文結(jié)點(diǎn)

typedef struct CPpmd7_Context_ {
  UInt16 NumStats;              //Stats array中元素個(gè)數(shù)
  UInt16 SummFreq;
  CPpmd_State_Ref Stats;
  CPpmd7_Context_Ref Suffix;
} CPpmd7_Context;
typedef struct {
  Byte Symbol;
  Byte Freq;
  UInt16 SuccessorLow;
  UInt16 SuccessorHigh;
} CPpmd_State;
  1. 第一個(gè)RAR3實(shí)例創(chuàng)建的同時(shí),一些上下文節(jié)點(diǎn)也同時(shí)被創(chuàng)建,Ppmd7_DecodeSymbol將p->MinContext
    向上移動(dòng)一次,知道找到相應(yīng)的符號(hào)為止。解碼器方法會(huì)因?yàn)镃InBufferException失敗。
  2. 由于下一個(gè)RAR3實(shí)例并沒有重置位,我們會(huì)繼續(xù)使用之前創(chuàng)建的PPMd模型。
  3. Ppmd7_DecodeSymbol使用一個(gè)新的范圍解碼器,并且p->MinContext!=p->maxContext
    它在p->MinContext中尋找對(duì)應(yīng)的符號(hào),但這個(gè)符號(hào)事實(shí)上已經(jīng)在p->MaxContext和p->MinContext之間
    的上下文,當(dāng)UpdateModel函數(shù)被調(diào)用,這個(gè)符號(hào)就會(huì)被重復(fù)添加到State數(shù)組

棧溢出和堆溢出

state指針數(shù)組固定大小且存放在棧中,并且在向其中添加新state指針時(shí)不會(huì)檢查長(zhǎng)度,故能構(gòu)建棧溢出
state內(nèi)容存放在堆中,溢出原理和上述相同

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容