【安全健行】(1):Hacker編程技能

   接觸安全領域也算四年了,大大小小的方向都看過一些,卻都未能精通,日漸感到自己實力的匱乏,因此自己決定今天開始來學習下Hack技術最爲核心的知識和技能:漏 洞挖掘與惡意代碼分析。由於主要涉及這個領域,因此所談與WEB安全腳本之類的關聯不大,凡事須追本,根深才能葉茂,希望可以利用近兩年的時間,小有所 成。
   今天要講的是Hack技術的編程基礎,談到基礎,大家都會給出一些有見解的意見,主流推薦就有C/C++、Java、Perl、Python、VB等; 進一步地還有SOCKET編程、系統編程等。自己當初也迷茫了好一陣子,大學學過C,研究生自學了C++,工作後又學習了Python。自己的感覺是:做 工程還是要用C++、Java,但是開發安全工具,還是Python更勝一籌,因爲易學易用且功能強大,非常適合寫自己的個人小工具。自己認爲,Hack 編程基礎應當涉及以下幾個方面:
1. C/C++編程語言;
2. 計算機內存知識;
3. Intel處理器的基本知識;
4. 彙編語言基礎;
5. gdb程序調試;
6. Python編程技能;
   下面逐一作簡要的說明。
一、C編程語言
   C的重要性在於,Unix及Windows的系統主要都是用C來編寫的,因此其底層的核心機制還是C的,儘管Widows系統越來越多的使用了C++架 構,但是其漏洞存在的根源卻和C大致相同,其漏洞存在的根本問題並未解決。C/C++語言可以幫助我們理解實現漏洞程序。這部分涉及漏洞的只需要掌握 main()、變量、函數調用、基本輸入輸出、字符串操作、條件/循環結構等基本知識。
   另外一個需要學習的是基本的編譯技能,推薦使用gcc,因爲可以根據自主選擇獲得目標文件(gcc -c)、彙編文件(gcc -S)、關閉棧保護(gcc -fno-stack-protector)等選項,可以說功能十分強大。
   具體的C/C++知識要點可以參考我的文集:http://blog.chinaunix.net/special/show/sid/1129.html

二、計算機內存
   計算機的內存是基本的讀寫存儲器,與我們程序最相關的爲RAM,這裏需要掌握以下幾個小的要點:
-1. 字節序:不同的廠商支持不同的寫入順序,有些廠商認爲數據寫入時應當由內存的低地址開始寫入,比如Intel,因此稱之爲“小端法”;另外一些廠商認爲應 當從高地址開始寫入,比如Moto,因此稱之爲“大端法”。後續討論shellcode時我們將會實際處理這兩種寫入方法。
-2. 內存中的程序佈局:每個進程當然擁有自己的內存空間,進程實際就是程序運行的資源容器,線程纔是具體運行的實例。這裏我們關注六種主要的內存節,它們是:
-2.1-:.text節,該節與二進制可執行文件的.text節部分一致,主要包含完成工作所需執行的機器指令,該節是隻讀的,若寫入則會導致段錯誤;
-2.2-:.data節,該節主要用來存儲全局初始化變量,如int a = 0,該節大小運行時固定;
-2.3-:.bss節,低於棧(below stack section),該節存儲未初始化的全局變量,如int b,該節運行時大小固定;
-2.4-:堆節,該節用於處理程序運行時動態分配的變量,並且分配的空間採取由低地址到高地址的寫入方式;
-2.5-:棧節,該節主要處理函數過程調用數據,包括函數內部的變量與語句,但是大多數系統上卻是採用由高地址到低地址的方式,這種棧的增長方式導致了魂衝去溢出的存在;
-2.6-:環境/參數節,該節用於保存進程在運行時可能用到的系統級變量的副本,如運行中的進程可訪問的路徑、shell名稱以及主機名等。
-3. 緩衝區、字符串與指針:這部分是C的基礎,就不需要再多說了吧?

三、Intel處理器
   處理器部分主要的知識是集中常用的寄存器,如通用寄存器EAX/EBX/ECX/EDX,如段寄存器CS/SS/DS/ES/FS/GS等等,這裏比較 重要的是ESP(擴展棧指針),我們經常需要藉助ESP來確定棧頂的位置;另一個則是EIP寄存器,其中存放着CPU將要執行的下一條指令的地址。
   更多的信息可以參考:http://blog.chinaunix.net/uid-26275986-id-4334522.html

四、彙編語言基礎
   做安全就不能不懂彙編,不一定能用匯編編程,但是讀懂彙編是基本的要求,不懂彙編的人終究難深入進安全問題的本質。彙編語言分爲ATT與NASM兩種格式,雖然其最終生成的機器指令完全一致,但是彙編語言表示卻有不同。比如ATT的操作數順序與NASM的相反:
將0x10寫入EAX寄存器:
ATT: Movl %eax, $0x10
NASM: mov 0x10, eax
   可以看出,ATT下常量需要使用$前綴,而寄存器則必須使用%前綴,且操作數順序相反。彙編語言學起來並不容易,所幸我們不是彙編程序員,我們需要的,僅僅是熟悉一些常用命令,需要的時候能夠看懂分析而已
1. mov:該命令用於將數據從源複製到目的地,複製成功後源數據不會移除;
2. add/sub:add命令用於將源數據與目的數據相加後結果保存在目的地;sub命令用於將源從目的中減去,並將結果存儲在目的地;
3. push/pop:push用於壓棧,即將一個數據寫入棧中;而pop用於彈棧,即從棧中取出棧頂元素,並且保存到操作數中;
4. xor:異或命令,其實是判斷二進制位是否相同的運算,不同爲異,即‘1’,相同爲‘0’,類似於mod2運算;
5. jne/jnz、je/jz、jmp:jne與jnz是一回事,當零標記ZF=0時跳轉;ZF=1時je和jz就會跳轉;jmp無論何時都會跳轉;
6. call/ret:用於函數過程調用與過程返回;
7. inc/dec:該命令用於將目的操作數遞增或遞減;
8. lea:該命令用於將源操作數的實際地址加載到目的操作數中,如lea eax, [dsi+4];
9. int:該命令可以向CPU拋出系統中斷信號,常見的是0x80,它用於向內核發送系統調用;
   除了基本的彙編命令,還需要了解彙編的尋址模式,主要是各種間接尋址與相對尋址,所幸都不難。另外一個技能是能夠使用gdb進行程序的調試,比如設置端點跟蹤等。

五、Python編程技能
   這部分主要能夠使用Python開發需要的工具就好了,基本的語法概念可以參考主流的教材書籍,也可以參考我的文集:http://blog.chinaunix.net/special/show/sid/1235.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章