君莫笑系列視頻學習(4)

接下來,視頻講解的都是各個例子(https://space.bilibili.com/14500640/

(1)程序中自身就含有system函數和"/bin/sh"字符串
(2)程序中自身就有system函數,但是沒有"/bin/sh"字符串
(3)程序中自身就沒有system函數和"/bin/sh"字符串,但給出了libc.so文件
(4)程序中自身就沒有system函數和"/bin/sh"字符串,並且沒有給出libc.so文件

1.ret2text

ret2text即需要我們控制程序執行程序本身已有的的代碼(.text)

 

nx則是no execution, 如果開啓的話就不能讓IP寄存器指向堆、棧

objdump -R 文件名    --->    可以查看文件中的函數

 

2.ret2shellcode

簡介

ret2shellcode顧名思義,就是return to shellcode,即讓程序中某個函數執行結束後,返回到shellcode的地址去執行shellcode,得到system(sh)的效果。

shellcode 指的是用於完成某個功能的彙編代碼,常見的功能主要是獲取目標系統shell。一般來說,shellcode 需要我們自己填充。

ret2shellcode的侷限性在於,在棧溢出的基礎上,要想執行 shellcode,需要對應的 binary 在運行時,shellcode 所在的區域具有可執行權限,即通常情況下我們checksec程序是NX保護就關閉的,否則當程序溢出成功轉入shellcode時,程序會嘗試在數據頁面上執行指令,此時CPU就會拋出異常,而不是去執行惡意指令。

 

這裏是up主的筆記:

這個時候就有兩個注意點
1NX:NX disabled
2 strncpy(buf2, &s, 0x64u);
第一句代表,我們把shellcode放在堆,棧或者其他數據段上,然後讓IP寄存器指向那裏就可以獲得shell
第二句代碼的意思是程序會把輸入複製到buf2去,buf2是什麼呢?
. bss : 0804A080 buf2 db 64h dup(?)
PIE:No PIE (0x8048000 )
PIE沒有開啓的情況下, bss段的地址是固定的,所以,我們把shellcode寫入bss段,然後跳轉過去就可以獲得shell了
下面實際寫一下exp
這裏提一下 ,現代的操作系統,都默認開啓了aslr保護措施,這個保護措施是由系統管理的,開啓時,堆,棧,libc的地址會隨機化
但是bss段沒有隨機化
這裏要先確定多少偏移能夠覆蓋返回地址
這裏提下,我是通過cyclic工具獲取偏移的, 也可以手動計算
這裏112個字節之後就是用來控制返回地址的數據,這個地址我們用buf2的地址,在前面112個字節裏面放入shellcode
這裏提一下, asm功能和系統, OS位數都有關,所以要指定程序的位數(設置binary)
pwntooLs的shellcraft模塊提供了一些寫好的shellcode ,大家可以去看文檔,

 

3.ret2syscall(該題是靜態鏈接)

ret2syscall,即控制程序執行系統調用,獲取 shell。

 

靜態鏈接是指在編譯階段直接把靜態庫加入到可執行文件中去,這樣可執行文件會比較大。

動態鏈接是指鏈接階段僅僅只加入一些描述信息,而程序執行時再從系統中把相應動態庫加載到內存中去。

 

所以在PWN中,如果是靜態鏈接的題目,問題就變得非常簡單了。

 

vmmap:查看現有的進程或者追蹤新的進程查看其電腦內存使用

第一步,ROPgadget --binary rop -- ropchain,會生成了一個rop chain,只要我們讓程序跳到這裏開始執行,就可以獲得shell

 

ret2libc 即控制函數的執行 libc 中的函數,通常是返回至某個函數的 plt 處或者函數的具體位置 (即函數對應的 got 表項的內容)。一般情況下,我們會選擇執行 system("/bin/sh"),故而此時我們需要知道 system 函數的地址。

 

 

4.ret2libc1

現在plt表中有system函數,但是參數不是‘/bin/sh’,但是程序中有‘/bin/sh’

 

內存中搜索字符串:ROPgadget --binary ret2libc1 --string '/bin/sh'

 

plt中放的是代瑪 (如果在plt表中存在某個函數,我們用這個地址相當於直接使用這個函數)

got中放的是數據


然後後面的四個a是執行完system的返回地址,因爲我們這裏直接獲得了shell,這個地址執行不到,陸使寫
p32 (0x8049720)這裏則是存放/ b1n/ sh的地址

 

將system函數的起始地址佈局到棧上是,相當於這裏去調用system函數,所以執行system函數之前會存放system函數的下一條指令的地址,再接下來是函數的參數

(該程序源代碼:https://download.csdn.net/download/qq_43935969/12119259

 

5.ret2libc2

現在plt表中有system函數,但是參數不是‘/bin/sh’,但是程序中也沒有‘/bin/sh’

但是程序有輸入點,所以就考慮將‘/bin/sh’先輸入到程序中,然後將地址給system做參數

 

這裏就是執行了gets(elf. bss( )+0x100)
然後執行了system( elf. bss( )+0x100)
中間通過一個gadget連接起來
然後程序執行到gets的時候會等待我們輸入
p. sendline( , /bin/sh\x00' )

 

research的最初想法:

pop eax的作用是平衡棧幀,因爲get函數有一個參數,而在(3)中提到過,參數有多少,返回的時候就要add多少,pop eax就可以讓esp+4,ret就可以結束get函數,而eip這裏都還沒變,所以繼續執行112之後的作爲返回地址

 

這是pwntools官網上對rop.search()的解釋,因爲‘/bin/sh’是兩個字節,所以需要8位

rop可以結束棧幀,get函數結束

 

6.ret2libc3

沒有system函數也沒有‘/bin/sh‘,那我們就要找到對應的.so庫獲取庫裏面對應的system函數的地址和/bin/sh的地址。

 

思路:

1.泄露 一個調用函數的地址

2.獲取 libc 版本

3.獲取 system 地址與 /bin/sh的地址

4.再次執行源程序

5.觸發棧溢出執行 system(‘/bin/sh’)
 

PIE沒開,說明.text段、got表和plt表都是不變的

 

查看函數中各個表有哪些(有哪些函數):objdump -R 名字

 

泄露 一個調用函數的地址:

exp:

(a)0x8048618是mian的返回地址,泄露了put的地址後返回到main處再次執行

(b)接受到泄露的四個字節後要u32,解包

(c)0x15ba0b是binsh的偏移地址,是在gdb調試中算出來的

binsh程序中的地址 - libc的地址

(4)第二次重定位問題?所以偏移地址改變,104

 

【注:system()函數調用/bin/sh來執行參數指定的命令,/bin/sh 一般是一個軟連接指向某個具體的shell

done!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章