zoukankan      html  css  js  c++  java
  • 调用门

    Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html

    调用门

    问题索引:

    1. 调用门的"门"这字的含义。
    2. 如果通过这扇门走?
    3. 为什么需要调用门?
    4. 为何构造call时数组前四位随便写?
    5. 调用门构造实验
    6. 远调用的特点?
    7. 远调用带参数实验
    8. 远调用提权实验
    9. 权限的CALL指令的门权限检查
    10.call调用门提权,iretd降权实验

    问题解答:

    1. 调用门的"门"这字的含义。

      门-通往另外一个世界的通道,同时也是一种控制的阻碍。2. 如果通过这扇门走?

     

      Segment - 段选择子,通过这个段选择子来替换代码段寄存器。
      Offset in Segment - 段内偏移,段只能提供基地址,但怎么走还是要看在基地址基础上计算偏移量的。
    3. 为什么需要调用门?

      方便权限控制,可以不改变R3层的调用方式的基础上改变调用权限来实现控制效果(写好的代码不变,但我可以让你不通过)。

    4. 为何构造call时数组前四位随便写?

      这四位应该本应该写偏移量的,但是调用门中自带着段内偏移,因此我们并不需要这四位,直接随便填写即可。

      

    5. 调用门构造实验

      实验原理:构造调用门,然后执行调用门中指向的函数。

        #include "stdafx.h"
        #include <stdlib.h>
        __declspec(naked) void callgate(){
            __asm{
                int 3;
                retf;
            
            }
        }
        int main(int argc, char* argv[])
        {
            char buf[6] = {0};
            *(int*)&buf[0] = 0x12345678;
            *(short*)&buf[4] = 0x4b;
            printf("%x
    ",callgate);
            getchar();
            __asm{
                call fword ptr buf;
            }
            system("pause");
            return 0;
        }

      windbg进行如下修改
      eq 8003f090 00cf9b00`0000ffff (代码段描述符)
      eq 8003f048 0040ec00`00901005 (调用门,指向代码段)

    6. 远调用的特点?
        call far,当使用调用门时,就是远程调用。
        远程调用即需要切换环境,至少保存四个值 ret,cs,ss,esp
        只要执行远call,其就会切换堆栈(下面实验我们就可以看出)


    7. 远调用带参数实验

      实验思路:我们在0环读取gdtr表,如果提权成功则可以读取,否则不可以读取。

        #include "stdafx.h"
        #include <stdlib.h>
        __declspec(naked) void callgate(){
            __asm{
                int 3;
                retf 0x4;
            
            }
        }
        int main(int argc, char* argv[])
        {
            char buf[6] = {0};
            *(int*)&buf[0] = 0x12345678;
            *(short*)&buf[4] = 0x4b;
            printf("%x
    ",callgate);
            getchar();
            __asm{
                push 0x12345678;
                call fword ptr buf;
            }
            system("pause");
            return 0;
        }

      windbg 修改 调用门参数 (承接上个实验)
      eq 8003f048 0040ec01`00901005 (添加一个参数)

      堆栈如下:

      

          从中我们可以看出,只要通过调用门,其会另其一套堆栈,同时还需要记住参数的压栈顺序,参数是在中间部分。
          另外,retf 0x4, 不仅平衡三环的堆栈,也是平衡零环的堆栈。


    8. 远调用提权实验

      实验思路:我们在0环读取gdtr表,如果提权成功则可以读取,否则不可以读取。

        // callgate.cpp : Defines the entry point for the console application.
        //
        
        #include "stdafx.h"
        #include <stdlib.h>
        
        int value = 0;
        __declspec(naked) void callgate(){
            __asm{
                //int 3;
                pushad;
                pushfd;
                mov eax,dword ptr ds:[0x8003f008];
                mov value,eax;
                popfd;
                popad;
                retf 0x4;
            }
        }
        int main(int argc, char* argv[])
        {
            char buf[6] = {0};
            *(int*)&buf[0] = 0x12345678;
            *(short*)&buf[4] = 0x48;
            printf("%x
    ",callgate);
            getchar();
            __asm{
                push 0x12345678;
                call fword ptr buf;
            }
            printf("%x
    ",value);
            system("pause");
            return 0;
        }

      实验效果


    9. 权限的CALL指令的门权限检查

        其需要经过两关来检查:
        门检查 max(CPL,RPL) <= DPL
        CPL >= 代码段的DPL
      
    10.call调用门提权,iretd降权实验
      iretd用于其中断返回的,注意其堆栈的变化。

      

        
        #include "stdafx.h"
        #include <stdlib.h>
        
        int value = 0;
        __declspec(naked) void callgate(){
            __asm{
                //int 3;
                pushad;
                pushfd;
                mov eax,dword ptr ds:[0x8003f008];
                mov value,eax;
                popfd;
                popad;
        
                
                pop eax;
                pop ebx;
                pushfd;
                push ebx;
                push  eax;
                
                iretd;
            }
        }
        int main(int argc, char* argv[])
        {
            char buf[6] = {0};
            *(int*)&buf[0] = 0x12345678;
            *(short*)&buf[4] = 0x48;
            printf("%x
    ",callgate);
            getchar();
            __asm{
                call fword ptr buf;
            }
            printf("%x
    ",value);
            system("pause");
            return 0;
    }
  • 相关阅读:
    css命名书写规范小结。
    不断学习,充实自己。
    【openGL】画正弦函数图像
    【openGL】画五角星
    【openGL】画圆
    【openGL】画直线
    【网络资料】Astar算法详解
    【Agorithm】一次一密加密解密算法
    【HTML5】 web上的音频
    【sicily】卡片游戏
  • 原文地址:https://www.cnblogs.com/onetrainee/p/12430549.html
Copyright © 2011-2022 走看看