成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

應對安全漏洞:如何將LFI變為RFI

新聞 安全
PHP文件包含漏洞的產生原因是在通過PHP的函數引入文件時,由于傳入的文件名沒有經過合理的校驗,從而操作了預想之外的文件,就可能導致意外的文件泄露甚至惡意的代碼注入。

前言

PHP文件包含漏洞的產生原因是在通過PHP的函數引入文件時,由于傳入的文件名沒有經過合理的校驗,從而操作了預想之外的文件,就可能導致意外的文件泄露甚至惡意的代碼注入。最常見的就屬于本地文件包含(Local File Inclusion)漏洞了。

常見漏洞代碼

if ($_GET['method']) {

   include $_GET['method'];

} else {

   include 'index.php';

}

一般情況下,程序的執行過程是當用戶提交url為 https://xianzhi.aliyun.com/sth.php?method=search.php 時,調用search.php里面的樣式內容和功能。直接訪問 https://xianzhi.aliyun.com/search.php 則會包含默認的index.php里面的樣式內容和功能。那么問題來了,如果我們提交),且1.jpg是由黑客上傳到服務器上的一個圖片,并在圖片的末尾添加了惡意的php代碼,那么惡意的代碼就會被當前文件執行,以此觸發本地文件包含漏洞。

有趣的發現

我和我的好朋友Mike Brooks一直致力于對一些開源的Web框架進行代碼審計工作,在對這些Web開源框架代碼審計的過程中,我們找到了一種將本地文件包含漏洞(LFI)轉換為遠程文件包含漏洞(RFI)的方法。并且依賴于我們駐留在Web服務器上的JAR包文件,我們發現了一個能夠執行任意代碼的方法。通常情況下,當以特定方式配置Web應用程序時,它將能夠加載Web服務器上的JAR包文件并在文件中搜索實現的java類。有意思的是,在Java類中,我們可以在正在被執行的java類上定義一個靜態代碼塊,具體如下所示:

public class LoadRunner {
    static {
        System.out.println("Load runner'ed");
    }

    public static void main(String[] args) {

    }
}

我們首先編譯這個java類,然后在代碼中加載它,具體實現如下圖所示:

現在,我們已經有了兩個有趣的發現:一個是可以在加載的JAR文件中插入執行代碼,另一個是在Web服務器上找到一個合適的文件路徑來加載JAR包文件。因此,我們現在必須找到的一種方式來讓應用程序以某種方式引用我們駐留在服務器上的JAR包文件。在這個探索的過程中,我們嘗試了很多的方法,包括去查看應用程序中的所有請求處理程序以確定能否進行文件上傳;甚至嘗試尋找可以在服務器上毒化文件的方法,以便將其轉化為JAR包文件,但是這些方法卻都沒有能夠奏效。盡管這樣,我們仍然沒有放棄去研究和探索,最終Mike Brooks想出了一個好主意。

文件描述符

​    一般情況下,大多數Web開源框架都會將上傳的文件落地到服務器的某個磁盤上,但文件的路徑是不可猜測的(通常使用GUID或其他隨機標識符來表示),如果我們不知道文件路徑,那又該如何去訪問上傳的文件呢?在Linux中,當一個進程有一個文件被打開時,它將在其 /proc/ 目錄中打開一個指向該文件的文件描述符。因此,如果我們有一個PID為1234的進程,并且該進程打開了磁盤上的某個文件,那么我們可以通過**/proc/1234/fd/***文件描述符來訪問該文件。這意味著,我們不需要猜測GUID或其他隨機值,我們只需要猜測HTTP請求處理程序的PID和上傳文件的文件描述符即可。因而用于訪問上傳文件的搜索空間就會大幅減少。不僅如此,如果我們已經有了LFI,加上磁盤上那些經常出現的、可以預測的PID(Web服務器上HTTP請求處理程序的PID)文件,因此獲取PID和文件描述符編號要比想象中簡單得多。

加載文件描述符

​    為了實現上面的方法,我們首先需要在程序中找到那些處理文件上傳的請求,之后嘗試通過Web開源框架中的LFI漏洞來查看所有PID文件描述符,并通過文件描述符來訪問我們在Web服務器上上傳的文件。在我們測試過的Web框架中,當訪問FILES字典時,這些文件描述符總是被緩慢加載,而Flask Web框架直接在HTTP GET請求填充了FILES字典字段,以下是超簡單的Flask應用程序:

# -*- coding: utf-8 -*-
import os

from flask import Flask, request

UPLOAD_FOLDER = "/tmp"

app = Flask(__name__)
app.config["UPLOAD_FOLDER"] = UPLOAD_FOLDER

@app.route("/", methods=["GET"])
def show_me_the_money():
    x = request
    import code
    code.interact(local=locals())

if __name__ == "__main__":
    app.run()

在這個應用程序中,我們有一個單一的處理程序,該處理程序允許在URL上掛載HTTP GET請求。然后我們在Ubuntu VM中運行這個程序,并通過HTTP GET請求將文件上傳到該服務器上。對于以前沒有使用過 import code 技巧的人來說,這是一個很好的方法來調試Python代碼和庫,因為在 code.interact 被調用時你將進入到python的REPL環境中去。

以下是通過HTTP GET請求上傳文件的簡單腳本:

# -*- coding: utf-8 -*-
import requests

response = requests.get(
    "http://127.0.0.1:5000/",
    files={
        "upload_file": open("/tmp/hullo", "rb"),
    },
)

而在 /tmp/hullo 的文件中,我們可以看到很多的“Hello World”:

然后,我們首先運行服務器,之后上傳文件,并進入Flask請求處理程序上下文中的python REPL環境,具體如下圖所示:

通過使用請求處理程序的PID,我們可以查看到磁盤上打開的文件描述符:

然后我們返回到REPL并訪問上傳的文件:

現在該文件已經在Web服務器中被訪問過了,此刻我們回到 /proc 目錄,看看是否可以找到上傳文件的內容:

果然,我們找到了上傳的文件!因此,對于我們正在評估的Web應用程序來說,我們確認通過這種上傳和引用文件的方法可以正常訪問到我們駐留在Web服務器中的JAR包文件!

我們可以通過 多次上傳相同的文件 來進一步減少文件路徑搜索空間,因此我修改了文件上傳的代碼使得可以上傳相同的九個文件:

# -*- coding: utf-8 -*-
import requests

response = requests.get(
    "http://127.0.0.1:5000/",
    files={
        "upload_file": open("/tmp/hullo", "rb"),
        "upload_file2": open("/tmp/hullo", "rb"),
        "upload_file3": open("/tmp/hullo", "rb"),
        "upload_file4": open("/tmp/hullo", "rb"),
        "upload_file5": open("/tmp/hullo", "rb"),
        "upload_file6": open("/tmp/hullo", "rb"),
        "upload_file7": open("/tmp/hullo", "rb"),
        "upload_file8": open("/tmp/hullo", "rb"),
    },
)

運行此腳本后,訪問處理程序中的 FILES 字典,并查看請求處理程序PID目錄中的 fd 目錄內容,我們看到所有上傳的文件都有打開的文件描述符:

因此,通過使用這種方法,我們可以保證具有特定號碼的文件描述符終將會指向我們上傳的文件。如果我們提交100個上傳文件的請求,可能文件描述符50指向的就是我們的文件!反過來,我們現在需要猜測的唯一值就是PID。

如何實施攻擊利用?

​    總而言之,為了引用上傳文件以達到攻擊的目的,這是一種大大減少搜索空間的方法,這在許多情況下可以使LFI成為RFI。如果你要使用此方法進行攻擊利用,請考慮以下事項:

  1. 通過我們對多個Web框架(Django和Flask)的分析發現,當訪問FILE字典時框架會延遲加載文件引用。因此,我們必須定位 訪問FILES字典的 請求處理程序 。一旦請求處理程序訪問了FILES字典,文件描述符將在請求處理期間一直保持打開狀態。

  2. 默認情況下,其他框架可能會填充這些文件描述符,而這正是我們下一步將要研究的內容。

  3. 當處理請求體中上傳的文件時,有些框架不區分不同的請求方式,這在一定程度上說明這種攻擊方法不僅限于非冪等的HTTP verbs。

  4. PID并不意味著隨機化。無論我們的目標是什么(Ubuntu上的Apache,Fedora上的Nginx等),如果我們希望將其轉化為漏洞,那么我們可以創建一個本地設置,并查看與Web服務器和請求處理程序相關聯的PID。一般來說,當我們將服務安裝到*nix時,它們將在機器重新啟動時以類似的順序啟動。由于PID也按順序分配,這意味著我們可以大大減少PID搜索空間。

  5. 請求處理程序需要訪問 所有要處理的上傳文件 的FILES字典 。這就是說,如果處理程序中的功能期望上傳的文件是PDF,以執行請求處理程序的中代碼,而此時我們也準備上傳一個JAR包文件,那么只要同時上傳這兩個文件即可,它們都將被賦予文件描述符。

  6. 嘗試找到加載文件描述符的請求處理程序,為了我們的代碼審計工作能夠順利進行,我們發現有一個處理程序會逐行處理一個文件的全部內容,所以我們上傳了一個巨大的文件,該巨大的文件中當然也包含了我們想要執行的JAR包文件。

  7. 請注意,如果您上傳的文件較小,則可能只讀入內存,并且不會打開任何文件描述符。當對Flask Web框架進行測試時,我們發現1MB以下的文件會被直接加載到內存中,而1MB以上的文件則放在磁盤上。因此,我們需要在JAR包文件中額外填充任何可供攻擊利用的有效載荷。

后續更新

​    后續我們對多個框架緩慢加載文件描述符這一問題進行了深入的研究和分析。最后我們發現對于Flask和Django來說,并不是FILES 被緩慢加載,而是請求體的內容只有在被訪問時才會被處理。因此,根據這個結論我們可以輕松定位那些訪問HTTP請求體數據的任何請求處理程序。一旦請求處理程序訪問了包含在請求體中的數據,文件描述符就會被填充。

Django框架中訪問請求體數據代碼如下所示:

通過此訪問請求填充的文件描述符如下所示:

Flask Web框架中訪問請求體數據的代碼如下所示:

通過此訪問請求填充的文件描述符如下所示:

責任編輯:張燕妮 來源: 安全技術社區
相關推薦

2018-06-21 07:04:12

2011-12-26 11:22:48

2019-12-19 14:58:23

黑客網絡安全云計算

2013-06-03 14:39:01

2010-07-26 15:37:12

telnet安全漏洞

2014-06-03 09:23:41

2014-06-03 11:36:18

2020-10-09 09:52:00

漏洞分析

2009-03-07 09:59:16

2021-05-12 10:46:23

漏洞BINDDNS服務器

2010-09-17 16:16:28

2010-03-05 15:46:05

2023-12-31 09:06:08

2022-07-06 11:50:43

漏洞網絡攻擊

2024-06-07 15:26:22

2017-08-15 17:39:52

2014-10-28 09:11:10

2013-08-27 10:48:06

2021-07-26 17:34:50

華為云數據庫漏洞GaussDB

2009-05-13 09:49:07

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品福利网站 | 国产精品a久久久久 | www.久草.com | 欧美精品一区二区三区四区五区 | 成人国产精品一级毛片视频毛片 | 欧美特级黄色 | 国产精品免费在线 | 国产精品一区二区在线 | 亚洲免费网 | 四虎在线观看 | 日本中文字幕一区 | 国产乱码精品一区二区三区五月婷 | 日本不卡免费新一二三区 | 久久草在线视频 | 欧洲毛片 | 久久久精 | 成年人在线观看视频 | 欧美精品一区二区在线观看 | 一级黄色片网址 | 国产高清在线 | 欧美日韩久久精品 | 午夜手机在线视频 | 3p视频在线观看 | 日韩欧美高清 | 色伊人| 国产97久久 | 国产精品一区二区视频 | 亚洲先锋影音 | 亚洲精品久久久久中文字幕欢迎你 | 精品国产一区二区三区久久影院 | 久久综合九九 | 国产亚洲精品精品国产亚洲综合 | 中文字幕在线视频精品 | 国产极品粉嫩美女呻吟在线看人 | 91视频a | 午夜精品久久久久久久久久久久久 | 欧美精品成人 | 中文字幕一区二区三区日韩精品 | 日日操日日舔 | 日韩在线欧美 | 亚洲成人一区 |