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

深入Linux | 如何在任意進程中修改內存保護(含PoC)

存儲 存儲軟件
在現代操作系統中,每個進程都有自己的虛擬地址空間(從虛擬地址映射到物理地址)。此虛擬地址空間由內存頁(某些固定大小的連續內存塊)組成,每個頁都有保護標志,用于確定允許此頁面訪問的類型(讀取,寫入和執行)。

 前言

最近,我們遇到一個非常具體的問題:改變任意進程的內存區域的保護標志。這項任務看似微不足道,但是我們著實遇到了一些麻煩,在此過程中也學到了關于Linux機制和內核開發相關的東西。以下是一些簡要概述,其中包括了當時采取的三種方案,每次也在尋求更好解決方案。

[[254657]]

 

概述

在現代操作系統中,每個進程都有自己的虛擬地址空間(從虛擬地址映射到物理地址)。此虛擬地址空間由內存頁(某些固定大小的連續內存塊)組成,每個頁都有保護標志,用于確定允許此頁面訪問的類型(讀取,寫入和執行)。這種機制依賴于架構頁表(有趣的是,在x64架構中,你不能使頁面只寫(write-only),就算你特意從操作系統請求,它也總是可讀的)。

在Windows中,你可以使用VirtualProtect或VirtualProtectEx這兩個API更改內存區域的保護。后者讓我們的任務變得非常簡單:它的***個參數hProcess是“要改變內存保護的進程的句柄”(參見MSDN.aspx))。

另一方面,在Linux中,我們并不那么幸運:更改內存保護的API是系統調用mprotect或pkey_mprotect,并且兩者始終在當前進程的地址空間上運行。 我們現在回顧一下在x64架構上的Linux中解決此任務的方法(我們假設是root權限)。

而在Linux中,我們就沒那么幸運了,更改內存保護的API是系統調用(mprotect或pkey_mprotect),并且兩者始終在當前進程的地址空間上運行。所以現在我們來回顧一下在Linux x64架構上解決此問題的方法(假設是root權限)。

方案一:代碼注入

如果mprotect總是作用于當前進程,那么我們就需要讓目標進程從它自己的上下文中調用它。這稱為代碼注入,可以通過許多不同的方式實現。我們選擇使用ptrace機制實現它,其允許一個進程“觀察并控制另一個進程的執行”(參見手冊),包括更改目標進程的內存的能力。此機制用于調試器(如gdb)和跟蹤程序(如strace)。使用ptrace注入代碼所需的步驟如下:

1. 通過ptrace附加到目標進程。如果進程中有多個線程,那就終止所有其他線程

2. 找到可執行內存區域(通過檢查/proc/PID/maps)并在那里寫操作碼(hex:0f 05)

3.根據調用約定修改寄存器:首先將rax更改為mprotect的系統調用號(即10)。然后三個參數(起始地址,長度和所需的保護)分別存儲在rdi,rsi和rdx中。***,將rip更改為步驟2中使用的地址

4. 恢復進程直到系統調用返回(ptrace允許你跟蹤系統調用的進入和退出)

5. 恢復被覆蓋的內存和寄存器,從進程中分離并恢復正常執行

這種方法是***個也是最直觀的方法,但是我們之后發現Linux中的另一種叫seccomp的機制會工作得更好。它是Linux內核中的一個安全工具,允許進程自己進入某種封閉狀態,除了read,write,_exit和sigreturn之外,它不能調用任何系統調用。不過也可以選擇任意系統調用及其參數來僅僅過濾指定的系統調用。

因此,如果進程啟用了seccomp模式并且我們嘗試將mprotect調用到其中,那么內核將終止進程,因為不允許此系統調用。所以我們要尋求更好的解決方案……

方案二:模仿內核模塊中的mprotect

由于seccomp,用戶態中每個解決方案都不可行,因此下一個方法肯定存在于內核態中。在Linux內核中,每個線程(用戶線程和內核線程)都由名為task_struct的結構表示,并且當前線程(任務)可通過指針訪問。內核中mprotect的內部實現使用指針current,所以我們首先想到的是將mprotect的代碼復制粘貼到我們的內核模塊,并用指向目標線程的task_struct的指針替換每次出現的current。

可能你已經猜到了,復制C代碼并不是那么簡單,其中有大量我們無法訪問的,未導出的函數,變量和宏。某些函數聲明在頭文件中導出,但內核不會導出它們的實際地址。如果內核是由kallsyms支持編譯的,那么這個特定的問題就可以解決,然后通過文件/proc/kallsysm導出所有內部符號。

盡管存在這些問題,我們仍以mprotect的本質進行嘗試,甚至僅用于教育目的。因此,我們開始編寫一個內核模塊,它獲取mprotect目標PID和參數,并模仿其行為。首先,我們需要獲取所需的內存映射對象,它表示線程的地址空間:

 

現在我們有了內存映射對象,就需要深入挖掘。Linux內核實現了一個抽象層來管理內存區域,每個區域由結構vm_area_struct表示。為了找到正確的內存區域,我們使用函數find_vma,它通過所需的地址搜索內存映射。

vm_area_struct包含字段vm_flags,其以與結構無關的方式表示存儲器區域的保護標志,vm_page_prot以體系結構相關的方式表示。單獨更改這些字段不會真正地影響頁表(但會影響proc/PID/maps的輸出,我們已經嘗試過)。 你可以點擊這里獲取更多內容。

在深入研究內核代碼之后,我們發現了真正改變內存區域保護所需的最基本工作:

1. 將字段vm_flags更改為所需的保護

2. 調用函數vma_set_page_prot_func來根據vm_flags字段更新vm_page_prot

3. 調用函數change_protection_func更新頁表中的保護位。

這段代碼雖然有效,但它有很多問題,首先,我們只實現了mprotect的基本部分,但原始函數比我們做的要多得多(例如通過保護標志分割和連接內存區域)。其次,我們使用兩個內核函數,這些函數不是由內核導出的(vma_set_page_prot_func和change_protection_func)。我們可以使用kallsyms來調用它們,但是這很容易出問題(將來可能會更改它們的名稱,或者會改變內存區域的整個內部實現)。所以我們想要一個更通用的解決方案,不考慮內部結構。

方案三:使用目標進程的內存映射

這種方法與***種方法非常相似,因為我們希望在目標進程的上下文中執行代碼。但在這里,我們會用自己的線程中執行代碼,同時使用目標進程的“內存上下文”,這意味著:我們會使用其地址空間。

通過幾個API可以在內核態下更改地址空間,我們使用了use_mm。如文檔明確指出的那樣,“此例程僅用于從內核線程上下文中調用”。這些是在內核中創建的線程,不需要任何用戶地址空間,因此可以更改其地址空間(地址空間內的內核區域在每個任務中以相同的方式映射)。

在內核線程中運行代碼有一種簡單方法,就是內核的工作隊列接口,它允許你使用特定例程和特定參數來安排工作。我們的例程獲取所需進程的內存映射對象和mprotect的參數,并執行以下操作(do_mprotect_pkey是內核中實現mprotect和pkey_mprotect系統調用的內部函數):

 

當我們的內核模塊在某個進程(通過一個特殊的IOCTL)獲得更改保護的請求時,它首先找到所需的內存映射對象,然后使用正確的參數來調度工作。這個方案仍有一個小問題:函數do_mprotect_pkey_func不由內核導出,需要使用kallsyms獲取。與前一個解決方案不同,這個內部函數不太容易發生變化,因為它與系統調用pkey_mprotect有關,而且我們無需處理內部結構。

如果你有興趣,可以在github中找到這個PoC內核模塊的源代碼。

責任編輯:武曉燕 來源: FreeBuf
相關推薦

2018-12-03 11:05:20

內存代碼Linux

2019-11-06 15:58:54

Linux內存消耗進程

2019-12-16 10:43:38

Linux內存消耗進程

2018-07-27 05:08:58

2021-08-30 06:59:07

x86處理器內存

2023-03-05 16:40:07

linux進程內存

2010-08-05 16:08:12

輕松掌握DB2 9.5

2023-01-30 14:27:14

Linux進程

2018-05-31 11:58:06

Linux進程Early OOM

2023-01-27 09:17:02

操作系統虛擬化內存

2019-12-16 09:10:38

Linux中央處理器進程

2019-12-16 11:00:04

LinuxCPU進程

2015-10-22 13:07:29

USB設備權限Linux

2013-06-20 10:25:56

2018-06-05 08:51:04

Linux結束進程中止程序

2022-05-27 11:59:22

Linux內存CPU

2021-07-16 08:00:00

開發VSCode編輯器

2009-12-09 10:07:19

Linux靜態路由

2011-01-26 13:26:32

Linux進程

2017-07-21 13:25:33

LinuxMD5哈希恢復文件
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩成人在线网址 | 麻豆91av | 成人午夜精品一区二区三区 | 国产在线视频一区 | 国产亚洲精品久久久久动 | 午夜视频在线观看网站 | 成人免费视频久久 | 日韩精品久久久久 | 欧美日韩三级视频 | 香蕉久久网 | 国产免费一区二区三区最新6 | 97国产精品视频人人做人人爱 | 精品一区二区久久久久久久网精 | a久久久久久| 亚洲高清在线观看 | 一区二区亚洲 | 一区在线视频 | 欧美综合一区 | 日韩a在线| 在线亚洲电影 | 青草福利 | 久久久久久国产精品 | 久久精品高清视频 | 成人水多啪啪片 | 国产精品久久久久久久久免费 | 日本精品视频在线 | 国产欧美一区二区在线观看 | 亚洲网站观看 | 欧美日韩在线播放 | 九九av | 一区二区三区四区在线视频 | 日本电影免费完整观看 | 日韩中文字幕一区二区 | 国产不卡在线观看 | 天天人人精品 | 国产精品久久一区二区三区 | 亚洲第一成人av | 日本视频在线 | 成人日韩av | 欧美一区二区三区精品免费 | 久久一区精品 |