windows内核驱动 5-中断级与自旋锁
顺便复习操作系统了
WinOS 相关原理
中断级
如果有时间的话可以试着玩一玩这个游戏:https://github.com/plbrault/youre-the-os
在线:https://plbrault.github.io/youre-the-os/
或许在游玩的过程中你会自己总结出一套操作系统进程调度的一套方法,便于其他方法的理解
调度方式:抢占式
最小执行单元:纤程->线程->进程
中断级( Irql ) 0->2级别越来越高,高级别可以打断低级别
0:Pass level
1:Apc level
2: Dpc level
ISR延迟调用,硬件中断后,不那么紧急的任务放在DPC队列中
DPC访问换页内存,页面换到磁盘中pagefile.sys,引起换页缺页中断,如果换页中断无法打断DPC,然后就会访问无效地址,造成BSOD,所以DPC中最好不要使用换页内存,也即要使用nonpagedpool,而不要使用paged pool
hardware(io…)
强制打断:ipicall
自旋锁
有一间厕所,A进去后就锁上了 ...
windows内核驱动 4-内核注册表
使用内核注册表实现开机启动驱动等
内核注册表
驱动创建描述符SYM_NAME后,会出现在注册表计算机\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services中
启动项的名字为驱动的文件名,例如hevd_2
Start:2-开机自启动、3-手动启动、4-禁用,数字越小启动越早
打开注册表ZwCreateKey和ZwOpenKey
移动驱动启动位置并修改注册表
ZwCreateKey
12345678910111213141516171819NTSTATUS status = STATUS_SUCCESS;HANDLE hRegKey = NULL;OBJECT_ATTRIBUTES RegAttribute = { 0 };ULONG KeyOp = 0;InitializeObjectAttributes(&RegAttribute, RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL);status = ZwCreateKey(&hRegKey, KEY_ ...
windows内核驱动 3-文件操作
之前写过:windows内核驱动 1-环境搭建、windows内核驱动 2-页表探索
但是内容确实有点衔接不上,这里根据【Win Pwn】HEVD-内核栈溢出(上)中展示的基础技巧来继续
项目结构优化
之前写过的所有功能都在main.c中,新加入IoctlFuncs,这里来写所有的ioctl功能,那么就要重新设计MyControl
1234567891011121314151617181920212223PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);ULONG ioCode = pStack->Parameters.DeviceIoControl.IoControlCode;ULONG inLen = pStack->Parameters.DeviceIoControl.InputBufferLength;ULONG ioInfo = 0;switch (ioCode){case IOCTL_MUL:{ DWORDLONG inData = *(PDWORDLONG ...
【Win Pwn】Windows内核池笔记
文章来自blackhat 2021的文章《Windows-Heap-Backed-Pool-The-Good-The-Bad-And-The-Encoded》
原文链接:https://i.blackhat.com/USA21/Wednesday-Handouts/us-21-Windows-Heap-Backed-Pool-The-Good-The-Bad-And-The-Encoded.pdf
Youtube:https://www.youtube.com/watch?v=VvxNc8GTFfk
粗略的分配
内核动态内存:和R3中的对差不多
类型为可分页和不可分页,程序按照4KB分页,之前写过一点相关的:Joe1sn’s Cabinet | windows内核驱动 2-页表探索
旧API初始化中不会将内存置零,导致信息泄露
一些API
在RS5(Redstone 5)版本前(及Windows 1809,在2018年10月前的版本)
没有任何校验、加密等等,但是之后就变得复杂得多了(严重怀疑微软借鉴了glibc的内存管理)
新版本的池设计管理和R3下是同一个库
每一个独立的 ...
【免杀】Windows Inline Hook小结
Inline Hook还是挺好玩的
文章很短,只是打个总结,记录一些有趣的发现
写在前面
之前在学习hook的时候,发现抄的一段代码只能在Debug模式下运行,调试后发现MSVC很有趣的一个点
当我们使用Debug模式编译的时候,程序为了调试方便,会将所有函数加入这个表中
比如
123456789void oldtest() { MessageBoxA(NULL, "not hook", "test", NULL);}int main(){ oldtest();}
按照直觉
这里的call应该会直接来到函数的位置,但是真实情况并非如此
我们会发现一张跳表,根据距离这张表的地址差进行跳转,那段hook只是修改了这一段代码
x86 hook
首先是x86为啥叫32位架构,最突出的就是一个寄存器有32位(bit)大小,那么计算一下
1(1<<32)/int(1024*1024*1024) = 4
没错,32位的寄存器最多只能存放4GB个数字(比如从1到0x100000000),
由于要 ...
【免杀】PE文件分析
最近代码能力飞速提升,顺便复习一下
一般就是
DOS头:IMAGE_DOS_HEADER结构体
PE头:IMAGE_NT_HEADERS结构体
Section头:IMAGE_SECTION_HEADER结构体
OK,如果要分析PE文件的话,首先把文件读取出来
那么如何解析呢?这就是C/C++非常方便的一点:直接使用结构体转换,例如把地址值解析为数值
总体就是解释内存中的值
DOS 头
先看DOSHeader吧
123456789101112131415161718192021typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header WORD e_magic; // Magic number WORD e_cblp; // Bytes on last page of file WORD e_cp; // Pages in file WORD e_c ...
【Win Pwn】HEVD-内核栈溢出GS保护及绕过
HEVD中的栈溢出加上GS保护
还有一个知识点就是windows内核栈地址泄露
函数功能
在上三篇中讲的很清楚了,这里我关闭了KVAS
又是一段经典的栈溢出,但是有了内核的GS保护
编写exploit
这里就不得不提到Windows中一种Cannary的绕过方式了,通过try except的Handler进行绕过,很遗憾handler只在32位程序中才保存在栈上
查阅资料
https://paper.seebug.org/2017/#22
https://kristal-g.github.io/2021/02/07/HEVD_StackOverflowGS_Windows_10_RS5_x64.html
cookie值是存储在_data段的第一个
函数检查的部分,有一个异或
123456789101112131415161718192021222324252627281: kd> dqs rspffff8788`21979540 00000000`00000000ffff8788`21979548 ffffc186`261f98f0ffff8788`21979550 ...
【Win Pwn】HEVD-任意地址写
非预期方法,暂时不会放出来
HEVD练习-任意地址写
漏洞点
一点好玩的
传入一个结构体,得到结构体过后写入内容
结构体
12345typedef struct _WRITE_WHAT_WHERE{ unsigned int* What; unsigned int* Where;}arbitrary_write, *pArbitraryWrite;
这里我做一个比较有意思的事儿,比如修改某个变量的值
1234567891011121314151617181920printf("[*] Start Exploit\n");pArbitraryWrite payload = (pArbitraryWrite)malloc(sizeof(arbitrary_write));if (payload == NULL) { printf("[!] Malloc payload failed\n"); return;}int vuln = 0x10000;int pay = 0xDEADBEEF;printf(&qu ...
【内网】从PoC看JuicyPotato提权
从此认识到自己不是做win安全的料
个人认为JuictPotato的前身是著名的Rotten Potato
使用CoGetInstanceFromIStorage API 调用欺骗RPC,对代理进行身份验证.在此调用中指定了代理 IP/端口
RPC 向代理发送 NTLM 协商包
代理依赖的NTLM协商到RPC在端口135,被用作模板。同时,执行对AcceptSecurityContext的调用以强制进行本地身份验证
注:此包被修改为强制本地身份验证.
& 5. RPC 135和AcceptSecurityContext用NTLM Challenge回复
将两个数据包的内容混合以匹配本地协商并转发到RPC
RPC使用发送到AcceptSecurityContext(8.)的NLTM Auth包进行响应,并执行模拟
【PotatoAPI】创建COM监听器startCOMListenerThread
初始化WinSocket,创建非阻塞式socket,并监听-t端口。跳转到2,后面的就是监听循环中的
【LocalNegotiator】使用processNtlm ...
【内网】探索Windows内网的Kerberos协议
感恩学校扎实的密码学功底,分析起来也是很简单的
说白了就一张图
攻击方式
黄金票据
第三步中 使用 KDC 特定账户 Krbtgt 的 NTLM-Hash 时,如果我们有了该NTML-Hash那么就能做到伪造TGT
该方法由于需要DC的NTLM-Hash,所以用于留后门
假设我们拿到了DC上administrator权限的shell
抓取Hash
CS使用的命令为:lsadump
相关项目:https://github.com/Xre0uS/MultiDump
获得管理员SID
mimikatz一把梭
wmic useraccount get name,sid
切换到域内用户的普通权限,制作黄金票据
横向移动
先尝试访问文件夹
原因:https://support.microsoft.com/zh-cn/topic/ms16-101-windows-身份验证方法的安全更新程序说明-2016-年-8-月-9-日-be16a40d-d7e2-c4b2-d885-6a22cff3cb77
貌似是WinServer2012的硬伤了,虚拟机必须用一些补丁才能用vmt ...
【内网】环境搭建
Windows Server 2012 配置
怀念大学时光,在学网络配置的时候就是用的winserver 2012,最近想探究内网就翻出来学一学。
简单配置
vmware虚拟机安装就不多说了,主要是网络,我配置了两块网卡
NAT:连接到物理机网络
WinDC:构建vmware的虚拟局域网
关于vmtool安装
vmtool是通过DVD光盘的形式安装的,所以要开启自动检测;软盘也要相同的设置
装完了过后就很方便了
关闭防火墙
开启远程桌面
配置路由
添加角色和功能 里面选择
配置DHCP服务器(非必要)
添加角色和功能 里面选择
创建和激活作用域:工具->DHCP
AD活动目录配置
AD和域控制器DC都在虚拟机上。
为了测试,安排一个Win7
局域网
Windows 7客户机
配置内网静态IP,设置DNS为域服务器IP
配置DC域控
提升为域控制器
密码:!234rewq
设置Administrator账户的密码为$321qwer
创建用户组织
用户组织可以用于委派等,是对组操作的最小单位
使用部门->个人的划分
这里就 ...
【Win Pwn】HEVD-内核栈溢出(下)
上:https://joe1sn.eu.org/2024/01/25/win-hevd-exp-stackoverflow-I/
中:https://joe1sn.eu.org/2024/01/25/win-hevd-exp-stackoverflow-II/
文章已在先知社区投稿:https://xz.aliyun.com/t/13365
本附录对第二章的以下几个遗留问题做出说明
user编程寻找ROPGadget
shellcode编写
Token提权
KVAS
user编程寻找ROPGadget
ROP全称加返回导向性编程,比如这一章用到的Gadget
12345pop rcxretmov cr4, rcxret
关于ret汇编本质上就是从栈帧中取出值,然后将ip寄存器设置为该值,等价于pop ip,这样就能完成函数调用的返回等等。
本章中当我们发生栈溢出时,就会把ret的位置设置为第一段gadget的位置
pop rcx就会将此时栈顶的值0x00000000002506f8存入rcx寄存器,然后ret又从栈顶取出地址mov_rc4_rcx_ret,然后rip寄存器就跳 ...
【Win Pwn】HEVD-内核栈溢出(中)
在上一篇中了解了与内核的交互模式,这里就可以开始做HEVD了
文章已在先知社区投稿:https://xz.aliyun.com/t/13364
编写交互模块
A. 计算IO_CTL值
其实不用这步,但是可以当作更多的了解
在之前的交互中有这么一条定义功能号
1#define IOCTL_MUL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x9888, METHOD_BUFFERED, FILE_ANY_ACCESS)
但是…HEVD逆向会发现是这样的
发现CTL_CODE也是个宏定义
123#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \)
其中,这里
DeviceType -> FILE_DEVICE_UNKNOWN = 0x22
Function -> = 0 ...
【Win Pwn】HEVD-内核栈溢出(上)
开始做HEVD来熟悉windows的内核漏洞利用方式时,发现大多数的资料依旧基于windows7,但是目前主流的操作系统已经是win10,所以还是得更上时代潮流的
文章已在先知社区投稿:https://xz.aliyun.com/t/13363
0. 前置环境
更基础
WIndows10 Vmware虚拟机
Visual Studio 2019,有WDK
Windbg Preview(我用单纯是觉得更好看)
最重要的HEVD项目:https://github.com/hacksysteam/HackSysExtremeVulnerableDriver,我直接下载的3.00 Release版
我使用的Windows版本是
I. 编程环境
如果你想快速搭建一个驱动开发环境可以参考B站上的一些资料,如:配置驱动开发环境
如果按照步骤vs没有KernelModDriver这一模板,找到vs目录的WDK.vsix双击即可
一段驱动的主要代码,在main.cpp中编写
123456789101112131415161718192021#include <ntifs.h>#inc ...
【漏洞挖掘】记一次痛苦的VxWorks路由器漏洞挖掘
问题多又多
记一次痛苦的VxWorks路由器漏洞挖掘
路由器很老了,是Mercury MW300R的某个版本,网上找不到固件,所以最开始想用uart进shell
拆开过后可以快速找到UART引脚
UART调试
I 打开UART
路由器断电,然后把万用表调到测接地,黑笔随便找一个电路板上的接口(我用的wifi天线的),红笔测口子,响的那个就是接地
接着路由器连上电源,万用表调到测电压,黑笔随便找一个电路板上的接口,红笔挨个测试接口
如果为3.3V左右,那么是电源线(3.3V)
如果为0V,为接地(GND)
如果为2.5V左右,为TXD(路由器的Write)
如果不断跳动,为RXD(路由器的Read)
然后第一点不寻常的就来了
我在测试的时候只能通过排除法筛选出了RXD,我的RXD一直为0V
这个时候通过
1234FT232: 3.3V -> 路由器: 3.3vFT232: GND -> 路由器: GNDFT232: RXD -> 路由器: TXDFT232: TXD -> 路由器: RXD
插上路由器电源线,但是不插插头,通过串口就能连上了
...
last_post
AES
1qazxsw23edcvfr4
1N1ahl+3mljPBkAs2CSlMlxCGeuML+X/YPgXKlAXMPimX9yyCj3q3qAZQpLCbqA1Q3KJRi4pF7LANa+yBxZCssnhNcdKHxX00F4kks5gk8LNqovzt3nEPBbzT5Lrw25LB8HAf04TlNp3wYnqSkz3WWbfHyveqkcM8d9ft/76hVxM08qlsludx4OOWxdrY4aub+dQ0UWIW9Y4Nle+rLB2Y9U+NyJ3rXxqguIl3o5hzAa7Sig0gPtBSMzJYC8pWPLB2BXfZDGDRYJeS6YafCPvgpAewfXMfrZN9nFqoe7Q3gyO1ZpQvxftM4dZ90YZQU4/SkFRyhYb1rtdqtl0PpH2qPwmwuSOXU0rfAWCNN8rVeSmrLCSmqAfwTf4HOrWtmBgXl+JlHLNgfwgZsvt7EBC9uPl2pzFRBTkVxx1jcZLNe3om9JvIWfA3aRJNyotqoEMi+wkZwyGE4HwE7zk8bZ9Jp/cX3l8p19 ...
【免杀】DLL注入小结
DLL 注入进化史
远程线程调用注入
这个是最简单的
这里我接受的是程序的进程PID和待注入DLL的路径szPath
12345678910111213141516171819202122232425void DLLinjector::DllOnLoad() { if (!this->Check()){ wcout << "The Process or DLL file not found\n"; return; } //向目标进程写入DLL的路径 SIZE_T dwWriteSize = 0; HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, this->dwPid); LPVOID pAddress = VirtualAllocEx(hProcess, NULL, 0x100, MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory(hProcess, pAddress, this->sz ...
【Win Pwn】基础栈溢出保护绕过
针对栈攻击的防护与绕过
GS
GS本质上和Linux GCC中的canary很相似,他在栈帧的结尾(EBP之前)插入一给DWORD类型的值,其副本存在于.data中。
在编译的时候并不会存在GS保护有下面几种情况
函数不包含缓冲区
函数被定义为具有变量参数列表
函数使用无保护的关键字标记
函数在第一个语句中包含内嵌汇编代码
缓冲区不是 8 字节类型且大小不大于 4 个字节
不过仍然可以采用#pragma strict_gs_check 强制启用GS保护
12345678910111213#include "string.h"int vulfuction(char* str){ char arry[4]; strcpy(arry, str); return 1;}int main(){ char* str = "yeah,i have GS protection"; vulfuction(str); return 0;}
绕过方式要漏洞类型灵活选择
如果是可以泄露那么泄露后拼接再溢出
再 ...
【Win Pwn】基础栈溢出利用
[Win Pwn] 基础栈溢出利用
window下无保护的栈溢出加载shellcode
程序
123456789101112131415161718192021222324252627#include <stdio.h>#include <string.h>#include <stdlib.h> void vuln(){ char password[6] = "ABCDE"; char str[6]; FILE *fp; if(!(fp=fopen("password.txt","r"))) exit(0); fscanf(fp,"%s",str); str[5]='\0'; if(strcmp(str,password)==0) // fprintf(stderr,"OK.\n"); printf("OK.\n"); else // fprintf(stderr,"NO.\n&qu ...
【CTF】2023 Google CTF WriteUp与复现
端午节打的比赛,事情比较多没怎么看题,指导学弟做了下,这里来个复盘。
开始CTF的复健之路吧。
Pwn
WRITE-FLAG-WHERE
最简单的一道pwn,没有开ASLR保护。当时我的机器跑不起来,学弟的能跑,和他一起分析。
程序的主逻辑是读取/proc/self/maps来读取存在的内存(gdb中的vmmap就是这样实现的),然后把 flag 读取到一个全局变量中,最后我们可以在任意一个地址写入任意长度(<0x7f)的flag中的字符串。
当时我们是在arch上做的,使用gdb能看到输出,然后尝试将flag覆盖内存中的提示语句
那么地址就是 *$rebase(0x21E0),尝试远程
得到flag
CTF{Y0ur_j0urn3y_is_0n1y_ju5t_b39innin9}
WRITE-FLAG-WHERE 2
当时离做出来差了亿点点。
保护没变,但是删除了之前的字符串修改点。后来我看到了有一段无关的代码段
后来想这道题快想魔怔了
【未解出】使用sscanf覆盖
挺疯狂的一个想法,由于死循环内不存在输入,但是sscanf会根据你的输入去匹配,然后我们又知道f ...