zergRush (CVE-2011-3874) 提權(quán)漏洞分析
最近(終于)轉(zhuǎn)Android了,2011年著名的zergrush是接觸的第一個(gè)ROOT漏洞。雖然它已經(jīng)過(guò)氣了,只影響Android 2.2 - 2.3.6,但覺(jué)得還是有必要記錄一下分析所得。
市面上各種ROOT工具基本都包含zergrush,大多是開(kāi)源的zergRush.c直接編譯而來(lái)。已有的分析文章:
tomken_zhang,漏洞 — zergRush,漏洞 — zergRush (補(bǔ)充)
Claud,?Android提權(quán)代碼zergRush分析
分析內(nèi)容集中在zergRush.c的代碼結(jié)構(gòu)上,對(duì)漏洞原理沒(méi)有解析,或者錯(cuò)誤地認(rèn)為是棧溢出。其實(shí)CVE-2011-3874已經(jīng)描述得很明白,這個(gè)漏洞的本質(zhì)是"use after free"。
1. 棧溢出?No.
漏洞存在于/system/bin/vold這個(gè)root身份的系統(tǒng)程序。具體地,vold調(diào)用了libsysutils.so,真正有問(wèn)題的是這個(gè)so。再具體地,問(wèn)題出在/system/core/libsysutils/src/FrameworkListener.cpp的FrameworkListener::dispatchCommand方法。
它在棧上分配了一個(gè)固定大小的數(shù)組argv,
void?FrameworkListener::dispatchCommand(SocketClient?*cli,?char*data)?{ ????FrameworkCommandCollection::iterator?i; ????intargc?=0; ????char*argv[FrameworkListener::CMD_ARGS_MAX]; ????chartmp[255]; ????char*p?=?data; ????char*q?=?tmp; ????bool?esc?=false; ????bool?quote?=false; ????intk;
?
?FrameworkListener::CMD_ARGS_MAX = 16。但后面填充argv數(shù)組時(shí),代碼并沒(méi)有檢查是否發(fā)生了越界。
if?(!quote?&&?*q?==?'?')?{ ??????*q?='