天天看點

Windows核心實驗

說明

教程是周壑老師在 B 站的 windows 核心實驗系列視訊,這隻是筆記,不是教程,大家想要學習可以去 B 站找視訊看

B 站空間連結:

https://space.bilibili.com/37877654

windows核心實驗第一集:

https://www.bilibili.com/video/av35033387

實驗環境配置

雙機調試配置

1、虛拟機添加序列槽:

\\.\pipe\com_1           

複制

Windows核心實驗

打開虛拟機的 C 盤下的 boot.ini,添加如下内容:

multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional Debug" /noexecute=optin /fastdetect /debugport=COM1 /baudrate=115200           

複制

Windows核心實驗

建立一個 windbg 的快捷方式,快捷方式目标中添加以下内容:

D:\anquan\CTF-tools\RE\windbg\windbg_cn_6.11.0001.404.exe -b -k com:pipe,port=\\.\pipe\com_1,baud=115200,resets=0 -y SRV*D:\anquan\symbol*http://msdl.microsoft.com/download/symbols           

複制

上面的部分内容要根據自己的情況更改一下

這是 windbg 所在目錄

D:\anquan\CTF-tools\RE\windbg\windbg_cn_6.11.0001.404.exe           

複制

這是符号路徑,聯網的時候會下載下傳在這個路徑裡

D:\anquan\symbol           

複制

Windows核心實驗

實驗 1:中斷提權

一些 windbg 指令

r eax           

複制

就是看一下 eax 的内容

dq 位址 L140           

複制

檢視位址的内容,後面跟的一個 L 可以檢視的長度,也就是 range

eq 8003f500 0040ee00`00081000           

複制

把 0040ee00`00081000 寫到 8003f500 的地方

實驗部分

使用指令

r idtr           

複制

檢視中斷描述表寄存器,找到中斷表的位置

idt 是中斷描述表,idtr 就是中斷描述表寄存器,用來記錄 idt 在什麼地方

Windows核心實驗

得到:idtr=8003f400

使用

dq 8003f400 -L40           

複制

檢視中斷描述表

Windows核心實驗

會看到 80548e00`000831a0 等這些差不多的,其實真正的是兩邊的 8 個,805431a0,中間的是一些屬性,後面再說

我們要做的就是:用程式寫一個函數,他會去觸發中斷,一旦執行中斷之後就可以執行異常,異常的處理位址是我們可以用 windbg 的 eq 指令寫入的,觸發異常之後就可以執行高權限的指令了

具體做法是構造一個裸函數,這個裸函數是我們用來執行高權限代碼的地方,這個函數的入口就是 401000

使用

eq 8003f500 0040ee00`00081000           

複制

把 00401000 寫到 8003f500 的地方

(這裡注意應該是 ee00 而不是 8e00,否則使用者态的程序是沒法通路的,ee 與 e8 的差別是 ee 允許使用者态來觸發,而 e8 隻允許核心态)

Windows核心實驗

比如普通的 int 3 斷點,直接在代碼裡面就可以執行,它的前半部分是 ee00,如果是 e800 的就不行

Windows核心實驗

寫一個函數,把函數的位址塞到向量表裡面,使用裸函數

然而每次運作位址都是不一樣的,在屬性裡面把随機位址關了填上一個固定位址

複制

#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
DWORD g_temp=0;
void _declspec(naked) IdtEntry()//這是一個裸函數,它的入口是401000
{
    _asm{
        mov eax,dword ptr ds:[0x8003f014]
        mov g_temp,eax
        iretd
        }
}
void go()//用來觸發異常的
{
    _asm int 0x20
/*這個地方,涉及到屬性了,要是 int 3 的話,因為屬性 ee00 是允許 ring 3 也就是使用者通路的,是以會提示觸發了一個斷點,如果是 int 0 的話就屬于你是使用者态卻想通路核心态的東西 8e00,會報錯,當正常出現這個異常的時候是由硬體通路這個位址的 */
}
void main()
{
    if((DWORD)IdtEntry != 0x401000)
    {
    printf("%p\n",IdtEntry);
    exit(-1);
    }
    go();
    printf("%p\n",g_temp);
    system("pause");
}           

複制

tips:

如果在 XP 上顯示不是有效的 win32 => 右鍵項目 => 屬性 => 配置屬性 => 正常 => 平台工具集 => 選擇 XP 的

主要是通過控制了一個異常,來執行高權限的指令,但我這個菜雞也玩不出什麼花樣來