3月30日名為danigargu的研究員在github上分享的該CVE-2020-0796漏洞本地提權相關的利用https://github.com/danigargu/CVE-2020-0796
如下所示,經過測試在1909的設備上可以實現提權,分析發現這個利用還是比較巧妙的,之前分析漏洞的時候遺漏了其中的一些細節。
可以看到整個發包過程其實和poc基本一致,壓縮數據包的主要內容是0x1108*A+(ktoken+0x40)。
如下所示為對應的數據包,由於1108個A的字符進行了壓縮所以在流量上是沒有這么多A的,這里可以看到下圖所示需要修改的token中_TOKEN_PRIVILEGES的地址,也就是說這一個數據包就能實現當前進程內核token _TOKEN_PRIVILEGES域的修改。
如下所示是整個漏洞利用的數據包,前0x10個字節是壓縮頭,偏移0x4的CompressedSegmentSize和0xc的offset兩個變量相加決定之后解壓縮buffer的大小,但是可以容易的知道這里是一個整數溢出,從而在之后拷貝解壓縮數據的時候導致越界寫,0x20開始的0x14個字節為對應的壓縮數據,其中藍色水印即為當前token的_TOKEN_PRIVILEGES的偏移,中間藍色框的部分為system token _TOKEN_PRIVILEGES的值,即通過這個包可以實現將當前token _TOKEN_PRIVILEGES修改位system的_TOKEN_PRIVILEGES。
這里之所以能利用就和Srv2DecompressData的解壓縮過程有一定關系了,當溢出分配了較小的解壓縮buffer v7之后(這里v7是一個buffer對象,對應的buffer指針在buffer+0x18處),調用函數SmbCompressionDecompress對0x20偏移的壓縮數據解壓,並將其拷貝到buffer對象的buffer指針中,這里拷貝的時候是從指針偏移0x10的位置開始拷貝,即會預留開始的0x10個字節,之后調用memove,將上圖中藍色框中的0x10個字節填充到buffer的開始預留的0x10長度的內存中。
如下所示為對應的buffer對象,偏移0x18處為實際的buffer指針,這里可以看到buffer指針指向的位置實際是在buffer對象的低地址處,也就是說通過解壓縮中拷貝溢出buffer,最終是可以修改對應的buffer對象的buffer指針的,又由於之后的memove會將壓縮數據包0x10-0x20處的數據(藍色框中攻擊者可控的0x10字節內容)復制到buffer指針開始至buffer+0x10處,這就給了攻擊者一次任意地址寫任意數據的能力,通過這個能力直接修改當前進程內核token的_TOKEN_PRIVILEGES來實現提權。
可以看到拷貝的起始地址為buffer+0x10,目標為buffer+0x11,長度為1107, 1107個A拷貝之后,正好后面就是buffer指針。
而我們的壓縮數據實際上還沒有拷貝完畢,還差之后的ktoken+0x40
此時buffer指針在拷貝完之后正好被修改為當前進程 token _TOKEN_PRIVILEGES的地址
之后調用memove進行拷貝,目標地址為buffer指針指向的地址,源地址為壓縮數據包中壓縮頭之后到壓縮數據0x20之間0x10長度的內容。這段內容實際也是攻擊者數據包構造時完全可控的system _TOKEN_PRIVILEGES的值,由於此時buffer指針指向的地址被修改為當前進程的_TOKEN_PRIVILEGES的地址,從而實現了向當前_TOKEN_PRIVILEGES寫入指定system的_TOKEN_PRIVILEGES的操作
如下所示,最終寫入f2ffffbc0000001f
如下所示為對應的system進程的_TOKEN_PRIVILEGES,可以看到其值固定為f2ffffbc 0000001f,這也就是我們需要將其修改為f2ffffbc 0000001f的原因。
最終修改當前進程的token _TOKEN_PRIVILEGES,實現提權。
這里也可以看到如果在處理解壓縮數據的時候,先直接將頭部之后到壓縮數據之前的藍框部分拷貝的解壓縮buffer中,再拷貝解壓縮數據,就不會出現這一個利用點了。
轉載請注明出處
參考鏈接