漏洞战争软件漏洞分析精要 学习笔记
(拖延癥越來(lái)越嚴(yán)重)
書非借不能讀也 , 時(shí)間匆匆 , 沒(méi)有讀完
也是由于自己 , 剛剛起步吧 閱讀還是有一定難度
所以 , 只能做個(gè)簡(jiǎn)簡(jiǎn)單單的總結(jié)了
對(duì)常見(jiàn)軟件漏洞的分類和簡(jiǎn)介
常見(jiàn)漏洞列表
- 棧溢出漏洞
- 堆溢出漏洞
- 整數(shù)溢出漏洞
- 格式化字符串漏洞
- 雙重釋放漏洞
- 雙重引用漏洞
- 數(shù)組越界訪問(wèn)漏洞
- OtherS
漏洞基本原理解析
棧溢出漏洞原理
先看代碼
原理
int main(int argc, char const *argv[]) {char *junk= "AAAAAAAAAAAAAAAA" //這里定義填充func(junk);return 0; }int func(char * str) {char overflow[10]; //這里就是在棧內(nèi)開辟空間(緩沖區(qū))strcpy(overflow, str); //這里發(fā)生溢出return 0; }這個(gè)就是經(jīng)典的棧溢出的原理代碼,
首先棧是從高地址向下增長(zhǎng)的(x86), 當(dāng)我們調(diào)用func時(shí)候站內(nèi)容會(huì)發(fā)生如下改變
對(duì)于過(guò)程的詳解見(jiàn)ZhiHu
1. 壓入返回地址(main函數(shù)內(nèi))
2. 壓入之前的函數(shù)棧幀(main)EBP(ESP - ESB 即為當(dāng)前棧幀)
3. 開辟當(dāng)前函數(shù)棧幀 (overflow[10])
從上到下就是321的結(jié)構(gòu)
在這樣的棧結(jié)構(gòu)下,我們通過(guò)不檢查長(zhǎng)度的strcpy 函數(shù), 把一個(gè)大于開辟棧空間的字符串 junk 裝入到overflow(緩沖區(qū))空間內(nèi)
于是就會(huì)導(dǎo)致,我們的2,1會(huì)被 junk 的數(shù)據(jù)給覆蓋掉, 這里就會(huì)發(fā)生嚴(yán)重的問(wèn)題了!
如果只是上面給出的 代碼段的話 ,可能只會(huì)有一個(gè) 內(nèi)存錯(cuò)誤的警告(內(nèi)容很熟悉 0x****** 不能為read 之類的)
原因很簡(jiǎn)單 , 當(dāng)我們向下覆蓋之后, AAAA 這個(gè)內(nèi)容會(huì)覆蓋掉我們之前 push 的 main 的返回地址, 這樣當(dāng)函數(shù)返回之后 直接pop到 EIP 的時(shí)候 返回地址是 0x41414141 (A的ASCII 碼 4*8 = 32),沒(méi)有誰(shuí)知道0x41414141那里是什么東西,自然各種問(wèn)題就出現(xiàn)了.
ret 相當(dāng)于如下的匯編指令
pop eipjmp eip如果我們通過(guò)傳入超長(zhǎng)字符串,實(shí)現(xiàn)緩沖區(qū)溢出 , 覆蓋了EIP的這段棧空間,也就是控制了EIP的值
那CPU下一步就可以執(zhí)行我們的shellcode了。
這張圖是一般的程序的棧空間,我們能控制的變量一般是在局部變量那個(gè)位置,我們溢出攻擊的時(shí)候一般先用0x90(NOP)junk填充(也成為滑板好像) ,
然后計(jì)算出buf的起止位置和到EIP的offset。然后布置shellcode。
應(yīng)用
這里只是簡(jiǎn)介,所以對(duì)應(yīng)用不多做解釋
重點(diǎn)就在這個(gè)返回地址, 隨意的AAAA 當(dāng)然是不行的,單當(dāng)我們發(fā)現(xiàn)了這個(gè), 把緩沖區(qū)塞入我們特定的一個(gè)返回地址 , 這樣函數(shù)返回后,就會(huì)返回到我們特定的地址 , 從而就有了無(wú)限可能, 比如我自己構(gòu)造的另一段函數(shù)(shellcode);
堆溢出漏洞原理
原理
應(yīng)用
分享深度好文堆溢出原理
整數(shù)溢出漏洞
這個(gè)其實(shí)不算是一種特定的漏洞,往往是因?yàn)檫@個(gè)漏洞的存在,導(dǎo)致了前兩中漏洞發(fā)生的可能
原理
在計(jì)算機(jī)存儲(chǔ)數(shù)據(jù)時(shí)候,當(dāng)然位數(shù)是有限的,精度也是有限的,
比如 int32 就是 -2^31~+2^32-1 (這個(gè)1 是被 0 占掉的) 最前面的一位就是我們的符號(hào)位
uint 就是 0~2^32-1
這個(gè)就是 導(dǎo)致漏洞發(fā)生的原因
當(dāng)
這時(shí)候再給 A 加上 1 ,就導(dǎo)致了整數(shù)溢出的發(fā)生
這時(shí)候 A 的值成為了 -2147483648
原理很簡(jiǎn)單,計(jì)算機(jī)執(zhí)行ADD 的時(shí)候,當(dāng)然不會(huì)顧及A 的類型 ,這樣的話,就是普通的二進(jìn)制加法 , 就導(dǎo)致了進(jìn)位,而且恰好進(jìn)位的是符號(hào)位 ,所以當(dāng)再進(jìn)行 ptr 解讀的時(shí)候 發(fā)現(xiàn)數(shù)字早已發(fā)生巨變
應(yīng)用
這里要結(jié)合實(shí)際環(huán)境進(jìn)行應(yīng)用,
多數(shù)情況是變量的類型不匹配,導(dǎo)致了問(wèn)題所在
比如 i(unsigned short) = j(int)
當(dāng)j > 65535 時(shí)候 如65536 ;
存入 i 的空間時(shí)候,得到的值 就變成了1;
從而,導(dǎo)致了其他的 堆棧溢出的問(wèn)題
格式化字符串漏洞
原理
這個(gè)算是一個(gè)比較有意思的漏洞
可以發(fā)生在玩嗎很常見(jiàn)的 printf() 的 這個(gè)函數(shù)上面
代碼很簡(jiǎn)單,就是拷貝字符串,然后打印的事,
其實(shí)不然 , 如果我們規(guī)規(guī)矩矩的的 輸入buf2 一個(gè) helloworld 當(dāng)然是不會(huì)有問(wèn)題的,
但是當(dāng)我們傳入了特殊的字符 %s , %x 之類的效果就截然不同了.
當(dāng)傳入了%s 之后 ,printf 會(huì)認(rèn)為這個(gè)是個(gè)格式化的占位符,自然的 會(huì)繼續(xù)往后尋找參數(shù) ,用來(lái)補(bǔ)全這個(gè)位置,
于是就從于是就會(huì)尋找上一個(gè)參數(shù) ,
(printf 從右往左依次壓棧 , 所以 這個(gè)%s 就會(huì)使得 buf2 作為參數(shù)彈出 )
恰好就是我們的 傳入字符串
再者就是傳入%n , %hn
- %n 已打印字符串長(zhǎng)度 DW 輸入到指定變量
- %hn 已打印字符串長(zhǎng)度 W 輸入到指定變量
這樣通過(guò)構(gòu)造,就有了可乘之機(jī).
應(yīng)用
總結(jié)
以上是生活随笔為你收集整理的漏洞战争软件漏洞分析精要 学习笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 只允许运行一个实例的方法
- 下一篇: 去掉控制台程序的黑框框