歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux資訊 >> 更多Linux

Solaris8模塊加載嚴重系統漏洞

  最近,我在Solaris8上研究內核模塊問題時,意外發現,   Solaris8在執行內核模塊加載過程中,存在嚴重系統漏洞。   作為結果,任何普通用戶都將可以擁有root權限。我們知道   Solaris上出現了很多系統漏洞,他們中的很多是緩沖區溢出   漏洞,利用這種類型的漏洞必須要求含有該漏洞的可執行文件   具有setuid標志。而大多數有經驗的管理員已經將這些文件   的setuid標志去掉了。我下面介紹的方法不依賴任何其他的   setuid程序,就是說,你有執行程序的權利,你就是root了!     先讓我們了解一下內核模塊的基本知識,現代*作系統   大多擁有兩種工作狀態:核心態和用戶態。我們使用的一般   應用程序工作在用戶態,而內核模塊和最基本的*作系統核   心一同工作在核心態。   為什麼不在*作系統核心中實現所有功能,而要使用內   核模塊呢?因為隨著軟件技術的向前發展,*作系統核心需   要支持的功能越來越多,體積也越來越大,如果在*作系統   核心中實現所有功能我們就將擁有一個龐大而緩慢的*作系   統內核了。   內核模塊提供給我們一個較好的解決方案:在*作系統   啟動時,僅加載最核心的部分,隨著使用的應用程序需要,   再由*作系統動態的將相關的內核模塊加載到核心態,不用   的時候就可以將這些模塊卸載出內存。這樣我們的內核就可   以即功能強大,又小巧快捷了。     現在步入正題,我們知道黑客們總是將獲得root權限作   為目的,其實如果你可以在核心態運行你的程序,你一樣可   以獲得一般賬號沒有的權限,甚至比root權限更高級的權限。   因為*作系統只在用戶態對用戶權限進行限制。換句話說,   就是如果你可以在核心態運行你的程序,那麼你就可以為所   欲為了。所以一般*作系統都只准許root賬號來加載這種可   以運行在核心態的內核模塊,Solaris8也不例外   (modload命令)。   但是在Solaris8上還有一些其他的命令(或系統調用),   可以最終導致系統加載內核模塊,這些命令中的一些不需要   root賬號。當然對於那些總是加載固定內核模塊的命令,他   們也是安全的。那麼有沒有不需要root賬號而又可以指定加   載某個內核模塊的命令呢?   有!priocntl系統調用就是一個。priocntl是和進程切   換相關的一條系統調用,當他的第三個參數是PC_GETCID時,   他會加載在第四個參數中指定的內核模塊。例:   ......   pcinfo_t pcinfo;   strcpy(pcinfo.pc_clname, "RT");   if(priocntl(0,0,PC_GETCID,(caddr_t)&pcinfo)==-1)   printf("error = d!\n",errno);   else   printf("OK!\n");   ......   編譯並運行他,然後利用命令"modinfo grep RT"我們會發   現RT內核模塊被Solaris8加載了。   好!這是最關鍵的地方,也是產生漏洞的地方!priocntl   系統調用加載內核模塊的缺省路徑是/kernel/sched和   /usr/kernel/sched(除非你在/etc/system文件中指定的其他   路徑),而這兩個路徑及其中的文件都是只有root才有寫權限   的,我們無法將自己的內核模塊放到這兩個目錄中,但是!   priocntl居然支持"../"!!!改寫的代碼如下:   ......   pcinfo_t pcinfo;   strcpy(pcinfo.pc_clname, "../../tmp/gsu");   if(priocntl(0,0,PC_GETCID,(caddr_t)&pcinfo)==-1)   printf("error = d!\n",errno);   else   printf("OK!\n");   ......   然後編寫一個自己的內核模塊gsu,並放到/tmp目錄下(/tmp目   錄對我們是有寫權限的)。OK!Solaris8將gsu加載到內核了!!   這裡還有一個小問題,就是如果這個內核模塊成功加載了,   那麼Solaris8將使用這個內核模塊,那就不知道會發生什麼了。   可是我們的目的不是要加載這個內核模塊,我們只需要我們的   代碼運行在核心態就可以了,可以編寫模塊代碼如下:   #include   #include   _init()   {   /* 在這裡加入我們需要的代碼 */   return -1;   }   _info(strUCt modinfo *modinfop)   {   return -1;   }   在函數_init中返回-1,表示加載模塊失敗,但沒關系,我們   的代碼已經運行了。     可以利用了上述功能將一個文件的所有者修改為root。而   這個文件恰恰擁有可執行和setuid標志......   其實,我們使用上述功能修改文件所有者,已經是"大才   小用"了,利用它我們可以實現隱藏文件,隱藏進程,截獲系統   調用等等一切可以想到的功能。     那麼,我們如何防止這種黑客行為呢?   屏蔽priocntl系統調用?(怎麼做能實現?)   取消所有用戶的執行程序權限?(#¥#¥#¥)   我們還是盼望SUN公司盡早推出對應這個漏洞的patch吧!




Copyright © Linux教程網 All Rights Reserved