軟件安全PPT06:第四章 其他常見漏洞_第1頁
軟件安全PPT06:第四章 其他常見漏洞_第2頁
軟件安全PPT06:第四章 其他常見漏洞_第3頁
軟件安全PPT06:第四章 其他常見漏洞_第4頁
軟件安全PPT06:第四章 其他常見漏洞_第5頁
已閱讀5頁,還剩36頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第四章軟件漏洞知識(shí)點(diǎn)五:格式化字符串漏洞知識(shí)點(diǎn)六:整數(shù)溢出漏洞知識(shí)點(diǎn)七:攻擊C++虛函數(shù)知識(shí)點(diǎn)八:其他類型漏洞知識(shí)點(diǎn)五:格式化字符串漏洞格式化串漏洞和普通的棧溢出有相似之處,但又有所不同,都是利用了程序員的疏忽大意來改變程序運(yùn)行的正常流程。

首先,什么是格式化字符串呢,print()、fprint()等*print()系列的函數(shù)可以按照一定的格式將數(shù)據(jù)進(jìn)行輸出,舉個(gè)最簡單的例子:printf("MyNameis:%s","bingtangguan")

執(zhí)行該函數(shù)后將返回字符串:MyNameis:bingtangguan

該printf函數(shù)的第一個(gè)參數(shù)就是格式化字符串,它來告訴程序?qū)?shù)據(jù)以什么格式輸出。1.格式化字符串定義printf()函數(shù)的一般形式為:printf(“format”,輸出表列),

format的結(jié)構(gòu)為:%[標(biāo)志][輸出最小寬度][.精度][長度]類型其中類型有以下常見的幾種:

%d整型輸出,%ld長整型輸出,

%o以八進(jìn)制數(shù)形式輸出整數(shù),

%x以十六進(jìn)制數(shù)形式輸出整數(shù),

%u以十進(jìn)制數(shù)輸出unsigned型數(shù)據(jù)(無符號(hào)數(shù))。

%c用來輸出一個(gè)字符,

%s用來輸出一個(gè)字符串,

%f用來輸出實(shí)數(shù),以小數(shù)形式輸出。

控制format參數(shù)之后結(jié)合printf()函數(shù)特性就可以進(jìn)行相應(yīng)攻擊。當(dāng)格式化符號(hào)為%x時(shí)以16進(jìn)制的形式輸出堆棧的內(nèi)容,為%s時(shí)則輸出對應(yīng)地址所指向的字符串。特性一:格式化函數(shù)允許可變參數(shù)C語言中的格式化函數(shù)(*printf族函數(shù),包括printf,fprintf,sprintf,snprintf等)允許可變參數(shù),它根據(jù)傳入的格式化字符串獲知可變參數(shù)的個(gè)數(shù)和類型,并依據(jù)格式化符號(hào)進(jìn)行參數(shù)的輸出。如果調(diào)用這些函數(shù)時(shí),給出了格式化符號(hào)串,但沒有提供實(shí)際對應(yīng)參數(shù)時(shí),這些函數(shù)會(huì)將格式化字符串后面的多個(gè)棧中的內(nèi)容取出作為參數(shù),并根據(jù)格式化符號(hào)將其輸出。2.格式化字符串漏洞的利用—數(shù)據(jù)泄露調(diào)用時(shí)如果傳入”%x%x…%x”,則printf會(huì)打印出堆棧中的內(nèi)容,不斷增加%x的個(gè)數(shù)會(huì)逐漸顯示堆棧中高地址的數(shù)據(jù),從而導(dǎo)致堆棧中的數(shù)據(jù)泄漏。voidformatstring_func1(char*buf){charmark[]=“ABCD”;printf(buf);}下面以下述程序樣本為例,分析格式化字符串溢出的原理。#include<stdio.h>intmain(void){inta=1,b=2,c=3;charbuf[]="test";printf("%s%d%d%d\n",buf,a,b,c);return0;}編譯之后運(yùn)行(Debug模式):test123增加一個(gè)printf()的format參數(shù),改為:printf("%s%d%d%d%x\n",buf,a,b,c),編譯后運(yùn)行(Debug模式):

test12312C62E泄露內(nèi)存數(shù)據(jù)為什么輸出了一個(gè)12C62E?原因:函數(shù)調(diào)用,是要參數(shù)入棧的;printf函數(shù)會(huì)到入棧的參數(shù)位置去取參數(shù);在沒有給出%x的參數(shù)的時(shí)候,將自動(dòng)將棧區(qū)參數(shù)的下一個(gè)地址作為參數(shù)輸入。#include<stdio.h>intmain(intargc,char*argv[]){charstr[200];fgets(str,200,stdin);printf(str);return0;}編譯后運(yùn)行(Release模式)并輸入:AAAA%x%x%x%x我們成功讀到了AAAA:AAAA18FE84BB40603041414141(0x41就是ASCII的字母A的值)。思考:這個(gè)41414141是怎么讀到的?讀取任意內(nèi)存地址的數(shù)據(jù)讀取任意內(nèi)存地址的數(shù)據(jù)執(zhí)行printf(str)語句的時(shí)候,對比Debug模式和Relase模式的棧幀結(jié)構(gòu):charstr[200];fgets(str,200,stdin);printf(str);如果我們輸入AAAA%x%x%x%x返回結(jié)果為AAAA18FE84BB40603041414141那么輸入AAAA%x%x%x%s時(shí),通過%s讀到的數(shù)據(jù)為讀到數(shù)值A(chǔ)AAA讀到數(shù)值0x41414141從地址0x41414141上讀到字符串從地址0x41414141上讀到整數(shù)ABCD提交單選題1分#特性二:利用%n格式符寫入數(shù)據(jù)更危險(xiǎn)的是格式化符號(hào)%n,它的作用是將格式化函數(shù)輸出字符串的長度,寫入函數(shù)參數(shù)指定的位置。

%n不向printf傳遞格式化信息,而是令printf把自己到該點(diǎn)已打出的字符總數(shù)放到相應(yīng)變元指向的整形變量中,比如printf(“Jamsa%n”,&first_count)將向整型變量first_count處寫入整數(shù)5。3.格式化字符串漏洞的利用—數(shù)據(jù)寫入Sprintf函數(shù)的作用是把格式化的數(shù)據(jù)寫入某個(gè)字符串緩沖區(qū)。函數(shù)原型為:

intsprintf(char*buffer,constchar*format,[argument]…);

觀察如下程序(Release模式):intformatstring_func2(intargc,char*argv[]){charbuffer[100];sprintf(buffer,argv[1]);}如果調(diào)用這段程序時(shí)用”aaaabbbbcc%n”作為命令行參數(shù),將會(huì)怎么樣?首先“aaaabbbbcc”寫入buffer;然后從堆棧中取下一個(gè)參數(shù),并將其當(dāng)作整數(shù)指針使用,由于調(diào)用sprintf時(shí)沒有傳入下一個(gè)參數(shù),因而buffer中的前四個(gè)字節(jié)被當(dāng)作參數(shù),這樣已輸出字串的長度10就被寫入內(nèi)存地址0x61616161處。結(jié)果:數(shù)值10就會(huì)被寫入地址為0x61616161(aaaa)的內(nèi)存單元。通過這種格式化字符串的利用方式,可以實(shí)現(xiàn)向任意內(nèi)存寫入任意數(shù)值。運(yùn)行:Before:num=6666666666666666After:num=8特性三:自定義打印字符串寬度實(shí)驗(yàn):利用%n格式化符號(hào)和自定義打印字符串寬度,寫入某內(nèi)存地址任意數(shù)據(jù)#include<stdio.h>main(){intnum=66666666;printf("Before:num=%d\n",num);printf("%d%n\n",num,&num);printf("After:num=%d\n",num);}現(xiàn)在我們已經(jīng)知道可以利用%n向內(nèi)存中寫入值,如果我們寫的值(比如一個(gè)返回地址)非常大,怎么來構(gòu)造這樣的值?運(yùn)行:Before:num=66666666

66666666After:num=100關(guān)于打印字符串寬度的問題,在格式符中間加上一個(gè)十進(jìn)制整數(shù)來表示輸出的最少位數(shù),若實(shí)際位數(shù)多于定義的寬度,則按實(shí)際位數(shù)輸出,若實(shí)際位數(shù)少于定義的寬度則補(bǔ)以空格或0。我們把上一段代碼做一下修改并看一下效果:#include<stdio.h>main(){intnum=66666666;printf("Before:num=%d\n",num);printf("%100d%n\n",num,&num);printf("After:num=%d\n",num);}我們也可以使用%02333d這種形式。在打印數(shù)值右側(cè)用0補(bǔ)齊不足位數(shù)的方式來補(bǔ)齊,而不是空格。能寫入數(shù)據(jù)的格式化符號(hào)是%x%n%m%sABCD提交單選題1分知識(shí)點(diǎn)六:整數(shù)溢出漏洞整數(shù)溢出高級(jí)程序語言中,整數(shù)分為無符號(hào)數(shù)和有符號(hào)數(shù)兩類,其中有符號(hào)負(fù)整數(shù)最高位為1,正整數(shù)最高位為0,無符號(hào)整數(shù)則無此限制。常見的整數(shù)類型有8位、16位、32位以及64位等,對應(yīng)的每種類型整數(shù)都包含一定的范圍。當(dāng)對整數(shù)進(jìn)行加、乘等運(yùn)算時(shí),計(jì)算的結(jié)果如果大于該類型的整數(shù)所表示的范圍時(shí),就會(huì)發(fā)生整數(shù)溢出。(1)存儲(chǔ)溢出存儲(chǔ)溢出是使用另外的數(shù)據(jù)類型來存儲(chǔ)整型數(shù)造成的。例如,把一個(gè)大的變量放入一個(gè)小變量的存儲(chǔ)區(qū)域,最終是只能保留小變量能夠存儲(chǔ)的位,其他的位都無法存儲(chǔ),以至于造成安全隱患。

(2)運(yùn)算溢出運(yùn)算溢出是對整型變量進(jìn)行運(yùn)算時(shí)沒有考慮到其邊界范圍,造成運(yùn)算后的數(shù)值范圍超出了其存儲(chǔ)空間。

根據(jù)溢出原理的不同,整數(shù)溢出可以分為以下三類:

(3)符號(hào)問題整型數(shù)可分為有符號(hào)整型數(shù)和無符號(hào)整型數(shù)兩種。在開發(fā)過程中,一般長度變量使用無符號(hào)整型數(shù),然而如果程序員忽略了符號(hào),在進(jìn)行安全檢查判斷的時(shí)候就可能出現(xiàn)問題。

該函數(shù)將用戶輸入的數(shù)據(jù)拷貝到新的緩沖區(qū),并在最后寫入結(jié)尾符0。如果攻擊者將0xFFFFFFFF作為參數(shù)傳入len,當(dāng)計(jì)算size時(shí)會(huì)發(fā)生整數(shù)溢出,malloc會(huì)分配大小為0的內(nèi)存塊(將得到有效地址),后面執(zhí)行memcpy時(shí)會(huì)發(fā)生堆溢出。整數(shù)溢出的樣例可通過下面的代碼了解。char*integer_overflow(int*data,unsignedintlen){ unsignedintsize=len+1; char*buffer=(char*)malloc(size); if(!buffer)returnNULL; memcpy(buffer,data,len); buffer[len]=’\’;returnbuffer;}整數(shù)溢出一般不能被單獨(dú)利用,而是用來繞過目標(biāo)程序中的條件檢測,進(jìn)而實(shí)現(xiàn)其他攻擊。分析如下實(shí)例:#include<iostream>#include<windows.h>#include<shellapi.h>#include<stdio.h>#include<stdlib.h>#defineMAX_INFO32767usingnamespacestd;voidfunc(){ShellExecute(NULL,"open","notepad",NULL,NULL,SW_SHOW);//打開記事本}voidfunc1(){ShellExecute(NULL,"open","calc",NULL,NULL,SW_SHOW);//打開計(jì)算器}intmain(){ void(*fuc_ptr)()=func; charinfo[MAX_INFO]; charinfo1[30000]; charinfo2[30000];

freopen("input.txt","r",stdin); cin.getline(info1,30000,''); cin.getline(info2,30000,'');

shortlen1=strlen(info1); shortlen2=strlen(info2); shortall_len=len1+len2;

if(all_len<MAX_INFO) { strcpy(info,info1); strcat(info,info2); } fuc_ptr(); return0;}short型整數(shù)表示范圍為-32768~32767,當(dāng)len1+len2超過了short型整數(shù)的最大范圍后會(huì)變?yōu)橐粋€(gè)負(fù)數(shù),將滿足all_len<MAX_INFO的判斷條件,進(jìn)而進(jìn)入if的分支語句。于是繼續(xù)執(zhí)行if語句的時(shí)候,將info1與info2的內(nèi)容都寫進(jìn)info中。

思考:如何實(shí)現(xiàn)fuc_ptr的覆蓋,改變程序執(zhí)行?知識(shí)點(diǎn)七:攻擊C++虛函數(shù)多態(tài)是面向?qū)ο蟮囊粋€(gè)重要特性,在C++中,這個(gè)特性主要靠對虛函數(shù)的動(dòng)態(tài)調(diào)用來實(shí)現(xiàn)。C++類的成員函數(shù)聲明時(shí),若使用關(guān)鍵字virtual進(jìn)行修飾,則被稱為虛函數(shù)。虛函數(shù)的入口地址被統(tǒng)一保存在虛表(Vtable)中。對象在使用虛函數(shù)時(shí),先通過虛表指針找到虛表,然后從虛表中取出最終的函數(shù)入口地址進(jìn)行調(diào)用。C++面向?qū)ο笳Z言的漏洞C++虛函數(shù)和類在內(nèi)存中的位置關(guān)系如圖所示:(1)虛表指針保存在對象的內(nèi)存空間中,緊接著虛表指針的是其他成員變量;(2)虛函數(shù)入口地址被統(tǒng)一存在虛表中。C++面向?qū)ο笳Z言的漏洞對象使用虛函數(shù)時(shí)通過(1)調(diào)用虛表指針找到虛表,然后(2)從虛表中取出最終的函數(shù)入口地址進(jìn)行調(diào)用。如果虛表里存儲(chǔ)的虛函數(shù)指針被篡改,程序調(diào)用虛函數(shù)的時(shí)候就會(huì)執(zhí)行篡改后的指定地址的shellcode,就會(huì)發(fā)動(dòng)虛函數(shù)攻擊。通過下述代碼來復(fù)現(xiàn)虛函數(shù)攻擊。攻擊虛函數(shù)charshellcode[]=“xFC\x68\x6A…..\xA4\x8B\x42\x00”;classFailwest{public:charbuf[200];virtualvoidtest(void){cout<<"ClassVtable::test()"<<endl;};};

Failwestoverflow,*p;

voidmain(void){char*p_vtable;p_vtable=overflow.buf–4;intlen=strlen(shellcode);__asmint3;//人為增加一個(gè)斷點(diǎn)

p_vtable[0]=0x54;p_vtable[1]=0x8c;p_vtable[2]=0x42;p_vtable[3]=0x00;strcpy(overflow.buf,shellcode);p=&overflow;p->test();}得到虛表指針:為虛表指針位于對象overflow成員變量charbuf[200]之前,程序中通過p_vtable=overflow.buf-4定位到這個(gè)指針。這是我們能利用的緩沖區(qū),這意味著,惡意代碼shellcode被存儲(chǔ)到了overflow.buf位置。我們希望通過調(diào)用test虛函數(shù)的時(shí)候,跳轉(zhuǎn)到這個(gè)位置去執(zhí)行惡意代碼。但是,怎么讓調(diào)用test虛函數(shù)的時(shí)候,通過虛表指針找到的虛函數(shù)指針就是我們期待的目標(biāo)呢?2.修改虛函數(shù)指針:修改數(shù)組shellcode最后4位(虛表)來指向overflow.buf的內(nèi)存地址,即讓虛函數(shù)指針指向保存shellcode的overflow.buf區(qū)域。攻擊策略charshellcode[]=“xFC\x68\x6A…..\xA4\x8B\x42\x00”;classFailwest{public:charbuf[200];virtualvoidtest(void){cout<<"ClassVtable::test()"<<endl;};};

Failwestoverflow,*p;

voidmain(void){char*p_vtable;p_vtable=overflow.buf–4;……p_vtable[0]=0x54;p_vtable[1]=0x8c;p_vtable[2]=0x42;p_vtable[3]=0x00;…….}1.修改虛表地址:將對象overflow的虛表地址修改為數(shù)組shellcode的倒數(shù)第四個(gè)字節(jié)開始地址。充分利用overflow.buf這個(gè)緩沖區(qū):overflow.buf的地址為0x00428ba4,其倒數(shù)第四個(gè)字節(jié)開始地址為0x00428c54。Strlen里最后一個(gè)字符是0x00,需要加上。VCIDE,進(jìn)行實(shí)際調(diào)試的時(shí)候,在語句“p->test();”處轉(zhuǎn)入反匯編,繼續(xù)單步調(diào)試,可以看到攻擊成功,彈出failwest的對話框:虛表指針保存在靜態(tài)數(shù)據(jù)區(qū)對象的內(nèi)存空間類的聲明區(qū)對象的虛函數(shù)區(qū)ABCD提交單選題1分知識(shí)點(diǎn)八:其他類型漏洞注入類攻擊都具備一個(gè)共同的特點(diǎn):來自外部的輸入數(shù)據(jù)被當(dāng)作代碼或非預(yù)期的指令、數(shù)據(jù)被執(zhí)行,從而將威脅引入到軟件或者系統(tǒng)。根據(jù)應(yīng)用程序的工作方式,將代碼注入分為兩大類:二進(jìn)制代碼注入,即將計(jì)算機(jī)可以執(zhí)行執(zhí)行的二進(jìn)制代碼注入到其他應(yīng)用程序的執(zhí)行代碼中。由于程序中某些缺陷導(dǎo)致程序的控制器被劫持,使得外部代碼獲得執(zhí)行機(jī)會(huì),從而實(shí)現(xiàn)特定的攻擊目的;腳本注入,即通過特定的腳本解釋類程序提交可被解釋執(zhí)行的數(shù)據(jù)。由于應(yīng)用在輸入的過濾上存在缺陷,導(dǎo)致注入的腳本數(shù)據(jù)被執(zhí)行。1.注入類漏洞下面介紹幾種Web場景下的代碼注入攻擊。SQL(Structuredquerylanguage,結(jié)構(gòu)化查詢語言)是操作數(shù)據(jù)庫數(shù)據(jù)的結(jié)構(gòu)化查詢語言,用于讀取、更新、增加或刪除數(shù)據(jù)庫中保存的信息。應(yīng)用程序通過SQL語言來完成后臺(tái)數(shù)據(jù)庫中的數(shù)據(jù)的增加、刪除、修改和查詢。SQL注入是將Web頁面的原URL、表單域或數(shù)據(jù)包輸入的參數(shù),修改拼接成SQL語句,傳遞給Web服務(wù)器,進(jìn)而傳給數(shù)據(jù)庫服務(wù)器以執(zhí)行數(shù)據(jù)庫命令。如果Web應(yīng)用程序的開發(fā)人員對用戶所輸入的數(shù)據(jù)不進(jìn)行過濾或驗(yàn)證就直接傳輸給數(shù)據(jù)庫,就可能導(dǎo)致拼接的異常SQL語句被執(zhí)行,獲取對數(shù)據(jù)庫的信息以及提權(quán),發(fā)生SQL注入攻擊。(1)SQL注入(1)SQL注入strKeyword=Request[“keyword”];sqlQuery=

“SELECT*FROMArticlesWHEREKeywordsLIKE‘%”+strKeyword+“%’”;Hack’;DROPTABLEAritcles;--SELECT*FROMAritclesWHEREKeywordsLIKE‘%hack’;DROPTABLEAritcles;--%’--是注釋符,結(jié)果是以中間的分號(hào)為標(biāo)志分成兩個(gè)部分,執(zhí)行完“SELECT*FROMAritclesWHEREKeywordsLIKE‘%hack’”后,將執(zhí)行”DROPTABLEAritcles;”操作系統(tǒng)命令注入攻擊(OSCommandInjection)是指通過Web應(yīng)用,執(zhí)行非法的操作系統(tǒng)命令達(dá)到攻擊的目的。大多數(shù)Web服務(wù)器都能夠使用內(nèi)置的API與服務(wù)器的操作系統(tǒng)進(jìn)行幾乎任何必需的交互,比如PHP中的system、exec和ASP中的wscript類函數(shù)。如果正確使用,這些API可以豐富Web應(yīng)用的功能。但是,如果應(yīng)用程序向操作系統(tǒng)命令程序傳送用戶提交的輸入,而且沒有對輸入進(jìn)行過濾和檢測,就可能遭受命令注入攻擊。許多定制和非定制web應(yīng)用程序中都存在這種命令注入缺陷。在為企業(yè)服務(wù)器或防火墻、打印機(jī)和路由器之類的設(shè)備提供管理界面的應(yīng)用程序中,這類缺陷尤其普遍。(2)操作系統(tǒng)命令注入常用的ASP/PHP/JSP等web腳本解釋語言支持動(dòng)態(tài)執(zhí)行在運(yùn)行時(shí)生成的代碼這種特點(diǎn),可以幫助開發(fā)者根據(jù)各種數(shù)據(jù)和條件動(dòng)態(tài)修改程序代碼,這對于開發(fā)人員來說是有利的,但這也隱藏著巨大的風(fēng)險(xiǎn)。這種類型的漏洞主要來自兩個(gè)方面:(1)合并了用戶提交數(shù)據(jù)的代碼的動(dòng)態(tài)執(zhí)行。攻擊者通過提交精心設(shè)計(jì)輸入,使得合并用戶提交數(shù)據(jù)后的代碼蘊(yùn)含設(shè)定的非正常業(yè)務(wù)邏輯來實(shí)施特定攻擊。(2)根據(jù)用戶提交的數(shù)據(jù)指定的代碼文件的動(dòng)態(tài)包含。多數(shù)腳本語言都支持使用包含文件(includefile),這種功能允許開發(fā)者把可重復(fù)使用的代碼插入到單個(gè)文件中,在需要的時(shí)候再將它們包含到相關(guān)代碼文件中。如果攻擊者能修改這個(gè)文件中的代碼,就讓受此攻擊的應(yīng)用執(zhí)行攻擊者的代碼

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論