« 關於最近猖狂的病毒 Sasser Worm | 回到主頁面 | MT新知,MT3.0 Develop Edition 開始使用 »

May 14, 2004

Buffer Overflow 的範例程式


將此網頁加入【百度收藏】... 加入此網頁到【del.icio.us 書籤】 technorati

關於buffer overflow的範例程式,就如同上一篇文章裡面有提到,buffer overflow 主要是利用C++對於陣列大小沒有限制的概念,當你輸入一個過大的數值,回傳值(return value)會被蓋掉,即使你輸入錯誤的數值,你會也因為這樣而成功的登入電腦(或是使某個安全認證通過~~~)

一個好朋友(生魚片)寫了一個範例程式,但是我看了一下總是覺得哪裡怪怪的,因為我記得雖然記憶return value會在記憶體位置之中,但是很難確切抓出function的回傳位置就在變數之後,並且他設定的函數為void,照理說也是無法回傳的才對~所以我大膽猜測他所寫的程式主要是將func的副程式加以執行過後的結果,與我們原先探討的Buffer Overflow有所差異,所以我寫了一個範例程式如下:

在這個範例程式之中,副函示有數個變數宣告,buf[1],*p, r_c 所以記憶體分配方式如下(先宣告的記憶體位址比較後面,後宣告的記憶體位置比較前面)

               | 
                               +-----------------------+
                               | (other variable)      |
                               +-----------------------+
                               | 指標 p                |
                               +-----------------------+
                               | (other variable)      |
                               +-----------------------+
                               | r_c (1 bytes)         |
                               +-----------------------+
                               | (other variable)      |
                               +-----------------------+
                               | buf (1 bytes)         |
                               +-----------------------+
                               | (other data in stack) |
                               |           .           |
                               +-----------------------+
                               | return address of     |
                               | this function         |
                               |           .           |
                               |           .           |

當你在VC++編輯的時候,若是使用 [F11]來一個階段,一個階段的DEBUG,去一個個參照變數的位置(Address)的時候,你會發現以下的結果

按下去看全圖

也就是透過指標*p,回傳變數r_c會被該更改到,使得回傳的值變的有誤。

所以這個程式明明不該輸出『System passing 』卻因為回傳值變成r_c所以產生~~~~錯誤造成程式的錯誤

 



STL與泛行程式設計學習心得

由 Evan 發表於 May 14, 2004 將此網頁加入【百度收藏】... 加入此網頁到【del.icio.us 書籤】 technorati
引用
本文的引用網址:


以下是前來引用的連結 'Buffer Overflow 的範例程式' 來自 Blog E
迴響

但是你使用 (long)func
不就是在呼叫程式了嗎?而非讓陣列 overflow....
==============================================
這裡讓我澄清一下,
在 add[2]= (long)func;
並不是呼叫函式阿.
只是我觀察到在stack中.存放要return回main函式中的位址,可以透過add[2]來填入,所以我只是把func的address寫入其stack中.達成在func1最後,組合語言ret時.pop出來的返回為指為func1的位址,這樣不也是一樣的原理嗎???

生魚片 發表於 May 14, 2004 08:58 PM

厄.....我只是路過啦
順便發表一下感言.....
這世界上,果然有種世界語言,是我所不懂的啊

啊,雖然你寫的是中文
或簡單的英文單字
但是其中的邏輯與想像
應該就是我大腦缺的那一塊吧

好!!KUSO完畢

小貓 發表於 May 15, 2004 12:43 AM

to 生魚片~~
我明天在好好試試看
因為那個程式沒有傳回值,所以一直讓我以為不會去抓那個位置

to 小貓
隔行如隔山~~
大概再沒多久,你會在這個地方看到
1011001101111 一堆的機器語言
@__________________@

Evan 發表於 May 15, 2004 01:25 AM

總比每天在電視新聞上看到的!@#$#$#%%$^%$^*&#$%#$語言好吧...真的是....唉~~

生魚片 發表於 May 15, 2004 06:09 AM

在此總結一下生魚片與我的程式意義上的不同

我的想法是:
在輸入變數沒有控制大小之下,若是input buf使用array的方式存放,將使某些變數可以寫入可能是回傳的變數,也就是輸入一個比陣列大小還大的資料,會覆蓋到某些可能回傳的變數,使得認證的函示錯誤,進而得到控制權。

生魚片的方法是:
在程式碼中注入一個自己的函示(像是病毒或是後門程式),將其位置放入到陣列以外的位置(回傳值位址)使得函示會自動去執行他。

大致上是這樣,若有不對請糾正 :)

Evan 發表於 May 15, 2004 03:55 PM

生魚片的方法是:
在程式碼中注入一個自己的函示(像是病毒或是後門程式),將其位置放入到陣列以外的位置(回傳值位址)使得函示會自動去執行他。

我的想法是
我並不是改回傳值位址,而是更改用來存放呼叫此function的function位址,因為我們知道當我們呼叫function的時候會將我們自己程式現在的address存入stack中,等到function執行完畢.電腦在從stack將剛剛我們存放的位址pop出來然後跳回我們自己的程式並繼續往下執行,所以我只是更改存放我們程式位址的地方,將我們程式的位址改成別的函式位址.....我不太懂得解釋了..:P真慘的我..國文要好好學學了!!!

生魚片 發表於 May 17, 2004 02:37 PM

生魚片,我大概瞭解了
你就是更改掉程式裡面儲存程式的位置(將其換成自己函示的位置)(組合語言裡面的 PC與IP 結合出的位置)

讓電腦可以執行你想作的事情

只是我當初想問你,
1.你是怎麼查出來的
2.並且我們很難將這個設為變數傳入不是嗎?

Evan 發表於 May 17, 2004 10:41 PM

傳入喔..簡單阿...要把自己的函式位址傳入只要將函式的名稱給它就好...
例如傳入一個long就只要給他函式名稱.而不要加()
例如void func(void)這個函式..
要將此函式的位址傳入一個存放一個long的地方
long arr[10];
arr[0] = (long)func;就是把func的位址當作long來存放
至於怎麼查出來的...這..經驗吧..然後就是看組合語言的code阿..:D

生魚片 發表於 May 18, 2004 12:20 AM

感謝~~~
深感功力之不足~~ 看來得努力了
唱個『我要努力向上~~~』

Evan 發表於 May 18, 2004 11:57 AM

看不出來跟buffer overflow有什麼關係
不如叫亂用指標的後果
還有r_c是區域變數 怎麼能return 回去勒.......

由 C99 發表於 August 2, 2008 03:24 AM
發表迴響









記住我的資訊?




(請輸入以下的驗證碼)