無代碼執(zhí)行溢出攻擊
對于溢出攻擊來說,有時除了運行溢出代碼以外,我還發(fā)現(xiàn)了其它一些利用溢出方式,而且并不是所有的溢出都會彈出異常。某些溢出不允許攻擊者獲得控制權(quán),但是肯能允許他們讀取或操縱額外數(shù)據(jù)。例如,Logon.exe,這是一個允許管理員登錄某個服務的工具。由于登錄的密碼每次都是隨機產(chǎn)生的,很難猜測得到。如果不知道密碼,要想登錄服務就需要查看內(nèi)存(我假設這是沒有限制的)或使用某些狡猾的計策。讓我們看看Logon.exe是如何工作的。
C:\Documents and Settings\Czy>Logon.exe
USAGE: Logon.exe <username> <password>
試試輸入偽造的參數(shù):
C:\Documents and Settings\Czy>Logon.exe spy W7g6351a
Access Denied.
再試試輸入長字符串:
有點奇怪,當全部為字母a時,服務允許你登錄。再檢查一下,看看這種情況是否還會發(fā)生:
使用同一個用戶名、不同的密碼,登錄仍然有效!只要你指定了一個長密碼,無論這個密碼是否正確,程序都允許你登錄,這樣看來,你必須不把這種行為作為一個漏洞進行匯報。讓我們看看為什么會發(fā)生這樣的事。
Logon.exe中的類是如下定義的:
#define CREDENTIAL_LENGTH 64
class Login {
public:
Login();
void ClearCreds();
bool IsLoggedIn();
bool TryCreds(char *Username, char *Password);
virtual ~Login();
private:
char UserName[CREDENTIAL_LENGTH];
char PassPhrase[CREDENTIAL_LENGTH];
char CorrectPassPhrase[CREDENTIAL_LENGTH];
char Buffer[521];
};
這個類的定義中有幾個非常有趣的地方:PassPhrase和CorrectPassPhrase是順序存儲在內(nèi)存中的。查看一下用于檢查密碼是否正確的代碼:
bool Password::IsLoggedIn()
{
return(0==memcmp(passPhrase,CorrectPassPhrase,CREDENTIAL_LENGTH));
}
看起來一切正常。再來看看調(diào)用者。
bool Login::TryCreds(char *User, char *Password)
{
FillMemory(UserName,CREDENTIAL_LENGTH,0x00);
strcpy(UserName,User);
FillMemory(PassPhrase,CREDENTIAL_LENGTH,0x00);
strcpy(PassPhrase,Password);
retrun IsLoggedIn();
}
注意到了嗎?strcpy(PassPhrase,Password);這行代碼看起來很可疑。如果PassPhrase[]緩沖區(qū)溢出會怎樣呢?由于CorrectPassPhra[]緩沖區(qū)在內(nèi)存中的位置剛好在PassPhrase[]緩沖區(qū)的后面,很顯然,溢出的數(shù)據(jù)會覆蓋CorrectPassPhra[]緩沖區(qū)。如果Password的字節(jié)長度為2*CREDENTIAL_LENGTH,而且該密碼的前半部分和后半部分完全一樣,那么不管CorrectPassPhrase的真實數(shù)值是多少,函數(shù)IsLoggedIn返回的值都是true。
修補這個漏洞非常容易:只要檢查一下輸入的長度,如果過長,返回false就可以了。
bool Login::TryCreds(char *User, char *Password)
{
if ((strlen(User) < CREDENTIAL_LENGTH) &&
(STRLEN(pASSWORD) < CREDENTIAL_LENGTH)
{
FillMemory(UserName,CREDENTIAL_LENGTH,0x00);
strcpy(UserName,User);
FillMemory(PassPhrase,CREDENTIAL_LENGTH,0x00);
strcpy(PassPhrase,Password);
retrun IsLoggedIn();
}
else
{
retrun false;
}
}
尾聲:
測試一下修訂后的版本,你可以發(fā)現(xiàn)這個演示中的漏洞已經(jīng)得到了修補。如果你經(jīng)過仔細研究,其實它并不難。