r1就类似栈顶指针,第一条指令中,stwu最后的u表示update,指令中有效地址EA=r1+back_chain,该指令首先会将r1的值存放到EA中,接着会把有效地址EA存到r1里。back_chain对应新栈帧大小,是一个负值,此处为0x60,所以这里实际上就是开辟了一块新的栈帧,让r1指向新栈顶,同时在新栈顶处存储了上一个栈帧的栈顶,从而构成一个类似链表的东西,在之后帮助恢复栈帧。
mflr r0,把lr寄存器的值保存到r0中。接着stw将r0保存到栈上,从而在栈上保存了lr返回地址的值。指令中对栈变量的索引使用的是0x60+sender_lr(r1),r1已经指向新栈帧的栈顶,所以这里是通过栈顶指针索引栈上的局部变量,栈帧空间大小即0x60。
下一条stw指令将r31存储到栈上,然后执行mr把r1的值赋给r31。
由于test函数传入了一个参数n,是通过r3传递的。所以在之后看到首先把r3存到了栈上,接着不断连续调用lwz和stw指令,以r9为中间量,并通过r31索引,对栈上局部变量进行赋值。
接下来就是为函数调用布置参数了,这里由于我们使用的参数很多,会同时使用寄存器和栈变量进行传参。ppc中没有push、pop这样的指令,栈帧空间是提前设置好的,这里指令做的就是把参数从右往左把多出来的4个参数依次在栈上从高地址往低地址放置,第9个参数与栈顶位置中间还会留下一个字长的空间,用来存放下一个栈帧的返回地址;剩下的8个参数按照从右往左依次放入r3~r10中,指定执行时是从r10开始存放的。crclr是用来调整条件寄存器CR的。
lwz将栈上的值赋给r9,再用mr把r9赋给r3,其实就是在传递函数的返回值n
addi把上一个栈帧的栈顶地址存到r11里,然后索引到存放lr返回地址的位置把值放进r0,再通过mtlr r0把r0的值赋给lr寄存器,从而完成了返回地址的恢复。
接着lwz r31, -4(r11)即以上一个栈帧栈顶位置减4为有效地址取值存入r31,这一步是在恢复r31寄存器,对应开头进入函数时stw r31, 0x60+var_4(r1)在栈上保存的r31的值,因为它是非易失性寄存器需要恢复。
再把r11的值给r1,从而r1恢复指向原栈帧的栈顶,完成了函数的退栈操作。到这里也可以看出在ppc中是通过栈顶指针完成栈帧的开辟和弹出的,栈顶指针以链表形式链接,同时对局部变量的操作也是以栈顶为基址进行偏移索引的。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
mflr r0,把lr寄存器的值保存到r0中。接着stw将r0保存到栈上,从而在栈上保存了lr返回地址的值。指令中对栈变量的索引使用的是0x60+sender_lr(r1),r1已经指向新栈帧的栈顶,所以这里是通过栈顶指针索引栈上的局部变量,栈帧空间大小即0x60。
下一条stw指令将r31存储到栈上,然后执行mr把r1的值赋给r31。
由于test函数传入了一个参数n,是通过r3传递的。所以在之后看到首先把r3存到了栈上,接着不断连续调用lwz和stw指令,以r9为中间量,并通过r31索引,对栈上局部变量进行赋值。
接下来就是为函数调用布置参数了,这里由于我们使用的参数很多,会同时使用寄存器和栈变量进行传参。ppc中没有push、pop这样的指令,栈帧空间是提前设置好的,这里指令做的就是把参数从右往左把多出来的4个参数依次在栈上从高地址往低地址放置,第9个参数与栈顶位置中间还会留下一个字长的空间,用来存放下一个栈帧的返回地址;剩下的8个参数按照从右往左依次放入r3~r10中,指定执行时是从r10开始存放的。crclr是用来调整条件寄存器CR的。
lwz将栈上的值赋给r9,再用mr把r9赋给r3,其实就是在传递函数的返回值n
addi把上一个栈帧的栈顶地址存到r11里,然后索引到存放lr返回地址的位置把值放进r0,再通过mtlr r0把r0的值赋给lr寄存器,从而完成了返回地址的恢复。
接着lwz r31, -4(r11)即以上一个栈帧栈顶位置减4为有效地址取值存入r31,这一步是在恢复r31寄存器,对应开头进入函数时stw r31, 0x60+var_4(r1)在栈上保存的r31的值,因为它是非易失性寄存器需要恢复。
再把r11的值给r1,从而r1恢复指向原栈帧的栈顶,完成了函数的退栈操作。到这里也可以看出在ppc中是通过栈顶指针完成栈帧的开辟和弹出的,栈顶指针以链表形式链接,同时对局部变量的操作也是以栈顶为基址进行偏移索引的。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
漏洞利用
前期的利用就是通过不断用不同大小add和delete填充堆空间,溢出修改size从而造出unsorted bin并得到libc基址,然后通过溢出修改tcache的fd就能任意地址申请了。
在这里由于架构原因泄露出来的基址的计算和平时略有不同,不过计算方法也很简单,在文件所在目录下启动gdb-multiarch,就能直接在其中打印找到__malloc_hook地址位置,再进行索引即可得到libc基址
接着,按照一般的想法只需要劫持__free_hook,写入system地址,然后就能执行system("/bin/sh")getshell了。然而在如此想法下尝试了一下却发现走到了0xdeadbeef。重新看一下给的libc文件,发现里面的execve和system都被修改了
也就是说通过调用函数getshell的路都走不通了
但是,由于题目远程大概率也是用qemu-user模拟的,是可以直接执行shellcode,所以只要通过__free_hook控制执行流后跳转到我们写的shellcode上即可完成getshell
shellcode编写
尝试自己编写shellcode。这里和32位的ppc是类似的,具体实现时针对r3寄存器的设置我用了三种思路
要执行execve("/bin/sh", NULL, NULL),r3要指向对应字符串,可以将/bin/sh写到堆上然后让r3指过去。在调试的时候发现寄存器r9就是一个堆上的地址,所以第一种思路就是直接通过异或把值迁移到r3上再进行相应偏移的调整即可
shellcode做的就是首先清空r3、r4、r5寄存器,将r0赋值为11对应execve,然后通过异或和加法让r3指向/bin/sh,最后sc即执行系统调用
第二种思路是把地址拼出来,需要用到移位操作
addis是将计算结果左移2字节后再进行存储,sld是左移双字的意思。同时由于限制操作数的大小所以低两个字节需要两次加法得到
第三种思路是最通用的,本题由于我们无法控制lr寄存器,所以无法像上一道题目通过lr索引到/bin/sh。然而我们可以换一种思路,即通过shellcode在某个可写地址写入/bin/sh然后指向即可。在所有寄存器中,我们知道r1永远是指向栈空间的,而栈空间必然是可写的,所以不妨借由r1在栈上写入/bin/sh,从而确保r3参数的布置。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
前期的利用就是通过不断用不同大小add和delete填充堆空间,溢出修改size从而造出unsorted bin并得到libc基址,然后通过溢出修改tcache的fd就能任意地址申请了。
在这里由于架构原因泄露出来的基址的计算和平时略有不同,不过计算方法也很简单,在文件所在目录下启动gdb-multiarch,就能直接在其中打印找到__malloc_hook地址位置,再进行索引即可得到libc基址
接着,按照一般的想法只需要劫持__free_hook,写入system地址,然后就能执行system("/bin/sh")getshell了。然而在如此想法下尝试了一下却发现走到了0xdeadbeef。重新看一下给的libc文件,发现里面的execve和system都被修改了
也就是说通过调用函数getshell的路都走不通了
但是,由于题目远程大概率也是用qemu-user模拟的,是可以直接执行shellcode,所以只要通过__free_hook控制执行流后跳转到我们写的shellcode上即可完成getshell
shellcode编写
尝试自己编写shellcode。这里和32位的ppc是类似的,具体实现时针对r3寄存器的设置我用了三种思路
要执行execve("/bin/sh", NULL, NULL),r3要指向对应字符串,可以将/bin/sh写到堆上然后让r3指过去。在调试的时候发现寄存器r9就是一个堆上的地址,所以第一种思路就是直接通过异或把值迁移到r3上再进行相应偏移的调整即可
shellcode做的就是首先清空r3、r4、r5寄存器,将r0赋值为11对应execve,然后通过异或和加法让r3指向/bin/sh,最后sc即执行系统调用
sc1='''
li 3, 0
li 4, 0
li 5, 0
li 0, 11
xor 3,3,9
addi 3,3,36
sc
'''
第二种思路是把地址拼出来,需要用到移位操作
addis是将计算结果左移2字节后再进行存储,sld是左移双字的意思。同时由于限制操作数的大小所以低两个字节需要两次加法得到
sc2='''
li 3, 0
li 4, 0
li 5, 0
li 0, 11
addis 3, 4, 8
addi 4, 4, 19
sld 3, 3, 4
li 4, 0
addis 4, 4, {}
addi 3, 3, {}
addi 3, 3, {}+24
add 3, 3, 4
li 4, 0
sc
'''.format((binsh&0xff0000)>>16, (binsh&0xffff)/2, (binsh&0xffff)/2)
第三种思路是最通用的,本题由于我们无法控制lr寄存器,所以无法像上一道题目通过lr索引到/bin/sh。然而我们可以换一种思路,即通过shellcode在某个可写地址写入/bin/sh然后指向即可。在所有寄存器中,我们知道r1永远是指向栈空间的,而栈空间必然是可写的,所以不妨借由r1在栈上写入/bin/sh,从而确保r3参数的布置。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
目是一个经典的菜单题,有add,edit,show,deldete四个功能,代码很好审,这里我是用Ghidra查看伪代码。
简单来说add能够申请一个size小于0x91的chunk并写入信息作为book description,会有一个bookname与之一一对应,索引也使用name来索引,最多只能有三个book,bookname、book description和description的size均作为全局变量记录
edit能够二次编辑已经add的book内容,show打印,del删除。另外给的libc是2.31版本
漏洞发现
首先看到漏洞出现在myread中,存在off by one
修复方法很简单,只需要把local_14 <= param_2改成local_14 < param_2即可。右键选中patch instruction进行指令patch。这里将指令bge修改为bgt即可将<=改为<
众所周知,通常来说一个菜单题出现了off by one,再看一下申请的chunk大小要小于0x91,基本可以确定打tcache了,做题的思路也就很明确了。然而对于本题来说并非如此,调试一下发现,由于powerpc64是大端序,所以溢出的一个字节实际上会位于最高一个字节,无法覆盖掉chunk的size位
所以我们就需要继续审计代码了。可以发现在edit中存在问题。这里在使用myread对chunk内容进行修改后,会使用strlen重新测量内容长度,并用测出来的长度替换原本记录的长度。而myread每次又能够多写入一个字节,这样一来通过多次使用edit就能够造成更多字节的堆溢出,从而修改掉chunk的size位
动态调试
gdb-multiarch加载的脚本如下,其中架构设置为powerpc:common64,因为题目是64位的
set architecture powerpc:common64
file ~/pwn/hfu/pwn
b *0x4000002010
target remote localhost:1234
漏洞利用
前期的利用就是通过不断用不同大小add和delete填充堆空间,溢出修改size从而造出unsorted bin并得到libc基址,然后通过溢出修改tcache的fd就能任意地址申请了。
在这里由于架构原因泄露出来的基址的计算和平时略有不同,不过计算方法也很简单,在文件所在目录下启动gdb-multiarch,就能直接在其中打印找到__malloc_hook地址位置,再进行索引即可得到libc基址
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
简单来说add能够申请一个size小于0x91的chunk并写入信息作为book description,会有一个bookname与之一一对应,索引也使用name来索引,最多只能有三个book,bookname、book description和description的size均作为全局变量记录
edit能够二次编辑已经add的book内容,show打印,del删除。另外给的libc是2.31版本
漏洞发现
首先看到漏洞出现在myread中,存在off by one
修复方法很简单,只需要把local_14 <= param_2改成local_14 < param_2即可。右键选中patch instruction进行指令patch。这里将指令bge修改为bgt即可将<=改为<
众所周知,通常来说一个菜单题出现了off by one,再看一下申请的chunk大小要小于0x91,基本可以确定打tcache了,做题的思路也就很明确了。然而对于本题来说并非如此,调试一下发现,由于powerpc64是大端序,所以溢出的一个字节实际上会位于最高一个字节,无法覆盖掉chunk的size位
所以我们就需要继续审计代码了。可以发现在edit中存在问题。这里在使用myread对chunk内容进行修改后,会使用strlen重新测量内容长度,并用测出来的长度替换原本记录的长度。而myread每次又能够多写入一个字节,这样一来通过多次使用edit就能够造成更多字节的堆溢出,从而修改掉chunk的size位
动态调试
gdb-multiarch加载的脚本如下,其中架构设置为powerpc:common64,因为题目是64位的
set architecture powerpc:common64
file ~/pwn/hfu/pwn
b *0x4000002010
target remote localhost:1234
漏洞利用
前期的利用就是通过不断用不同大小add和delete填充堆空间,溢出修改size从而造出unsorted bin并得到libc基址,然后通过溢出修改tcache的fd就能任意地址申请了。
在这里由于架构原因泄露出来的基址的计算和平时略有不同,不过计算方法也很简单,在文件所在目录下启动gdb-multiarch,就能直接在其中打印找到__malloc_hook地址位置,再进行索引即可得到libc基址
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
探索Windows内核系列——句柄,利用句柄进行进程保护
方便在R3查看句柄信息的小工具
我们可以使用微软官方的工具Process Explorer来查看文件或进程被哪个进程使用着,它的官方文档在这里。
比如我使用CE打开了notepad.exe,使用Process Explorer查找句柄功能,搜索notepad.exe,即可找到对应占用它的进程。这在我们想删除一个文件却提示"该文件已被占用"时非常有用,可以直接搜索到占用它的进程。
句柄在内核中的存在形式
本节将通过实时内核调试结合逆向查看内核源代码的方式,来探索内核中的句柄结构。句柄结构经历各个windows版本到现在,变化非常大,这里使用的系统是Win10 1809。
Windows系统的句柄表主要有三种,第一种是系统全局PspCidTable句柄表,保存所有进程和线程的句柄,第二种是进程内部句柄表,保存该进程所打开的内核对象句柄,最后一种是系统进程system的全局句柄表,这几种句柄表对应的格式都是一样的。我们主要介绍进程中的句柄表。
_EPROCESS是进程在内核中内核对象结构,每个进程在内核中都有一个这样对应的内核结构来记录进程的信息。EPOCESS结构中的ObjectTable即该进程所有的句柄表,ObjectTable中的TableCode指向handle_table_entrys的首地址。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
方便在R3查看句柄信息的小工具
我们可以使用微软官方的工具Process Explorer来查看文件或进程被哪个进程使用着,它的官方文档在这里。
比如我使用CE打开了notepad.exe,使用Process Explorer查找句柄功能,搜索notepad.exe,即可找到对应占用它的进程。这在我们想删除一个文件却提示"该文件已被占用"时非常有用,可以直接搜索到占用它的进程。
句柄在内核中的存在形式
本节将通过实时内核调试结合逆向查看内核源代码的方式,来探索内核中的句柄结构。句柄结构经历各个windows版本到现在,变化非常大,这里使用的系统是Win10 1809。
Windows系统的句柄表主要有三种,第一种是系统全局PspCidTable句柄表,保存所有进程和线程的句柄,第二种是进程内部句柄表,保存该进程所打开的内核对象句柄,最后一种是系统进程system的全局句柄表,这几种句柄表对应的格式都是一样的。我们主要介绍进程中的句柄表。
_EPROCESS是进程在内核中内核对象结构,每个进程在内核中都有一个这样对应的内核结构来记录进程的信息。EPOCESS结构中的ObjectTable即该进程所有的句柄表,ObjectTable中的TableCode指向handle_table_entrys的首地址。
dt _EPROCESS
nt!_EPROCESS
+0x000 Pcb : _KPROCESS
+0x2d8 ProcessLock : _EX_PUSH_LOCK
+0x2e0 UniqueProcessId : Ptr64 Void
+0x2e8 ActiveProcessLinks : _LIST_ENTRY
+0x2f8 RundownProtect : _EX_RUNDOWN_REF
+0x300 Flags2 : Uint4B
......
+0x418 ObjectTable : Ptr64 _HANDLE_TABLE //我们要找的句柄表
......
+0x848 MmHotPatchContext : Ptr64 Void
0: kd> dt _HANDLE_TABLE
nt!_HANDLE_TABLE
+0x000 NextHandleNeedingPool : Uint4B
+0x004 ExtraInfoPages : Int4B
+0x008 TableCode : Uint8B //指向存放handle_table_entry的地方
+0x010 QuotaProcess : Ptr64 _EPROCESS
+0x018 HandleTableList : _LIST_ENTRY
+0x028 UniqueProcessId : Uint4B
+0x02c Flags : Uint4B
+0x02c StrictFIFO : Pos 0, 1 Bit
+0x02c EnableHandleExceptions : Pos 1, 1 Bit
+0x02c Rundown : Pos 2, 1 Bit
+0x02c Duplicated : Pos 3, 1 Bit
+0x02c RaiseUMExceptionOnInvalidHandleClose : Pos 4, 1 Bit
+0x030 HandleContentionEvent : _EX_PUSH_LOCK
+0x038 HandleTableLock : _EX_PUSH_LOCK
+0x040 FreeLists : [1] _HANDLE_TABLE_FREE_LIST
+0x040 ActualEntry : [32] UChar
+0x060 DebugInfo : Ptr64 _HANDLE_TRACE_DEBUG_INFO
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
该函数首先使用ObReferenceProcessHandleTable从EPROCESS的中获取HANDLE_TABLE,然后使用ExEnumHandleTable遍历该HANDLE_TABLE中的handle_table_entry。
结合伪代码,我们可以看出在ObFindHandleForObject函数中ExEnumHandleTable函数的EnumParameter参数为object_header;回调函数为ObpEnumFindHandleProcedure。接下来我们继续查看ObpEnumFindHandleProcedure函数中是如何使用object_header的。
我们知道在R3中,一个进程打开另一个进程进行读写,其过程为:A进程获取B进程句柄 -> A进程操作B进程句柄进行读/写。很明显,句柄是这里的关键介质。在阅读完上文后,我们知道了进程中的句柄对进程意味着什么。回顾handle_table_entry的结构,其中的GrantedAccessBits表示这个该进程可以通过该句柄所使用的权限。这意味着,如果我们修改A进程中的B进程句柄对应的handle_table_entry->GrantedAccessBits,便可以修改A进程对B进程的操作权限。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
BOOLEAN
ExEnumHandleTable(
IN PHANDLE_TABLE HandleTable,
IN EX_ENUMERATE_HANDLE_ROUTINE EnumHandleProcedure,
IN PVOID EnumParameter,
OUT PHANDLE Handle OPTIONAL
);
结合伪代码,我们可以看出在ObFindHandleForObject函数中ExEnumHandleTable函数的EnumParameter参数为object_header;回调函数为ObpEnumFindHandleProcedure。接下来我们继续查看ObpEnumFindHandleProcedure函数中是如何使用object_header的。
BOOLEAN
ObpEnumFindHandleProcedure (
PHANDLE_TABLE_ENTRY ObjectTableEntry,
HANDLE HandleId,
PVOID EnumParameter
)
*object_header == ((*(__int64 *)handle_table_entry >> 0x10) & 0xFFFFFFFFFFFFFFF0ui64)
汇编:
PAGE:000000014065FA82 sar r8, 10h ;算数右移
PAGE:000000014065FA86 and r8, 0FFFFFFFFFFFFFFF0h ;得到object_header地址
我们知道在R3中,一个进程打开另一个进程进行读写,其过程为:A进程获取B进程句柄 -> A进程操作B进程句柄进行读/写。很明显,句柄是这里的关键介质。在阅读完上文后,我们知道了进程中的句柄对进程意味着什么。回顾handle_table_entry的结构,其中的GrantedAccessBits表示这个该进程可以通过该句柄所使用的权限。这意味着,如果我们修改A进程中的B进程句柄对应的handle_table_entry->GrantedAccessBits,便可以修改A进程对B进程的操作权限。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
❤1
基于python的RPC Fuzz寻找可提权函数
解析idl生成的cs文件,使其变为可供python使用的函数集,含有uuid,版本,结构体和结构体内参数,方法和参数
用ntapidotnet遍历出可供c#调用的idl文件
https://github.com/tyranid/WindowsRpcClients中有对应的导出方法,或直接引用他提供的
但是在c#中调用函数需要using引入,这样就没法遍历所有文件自动fuzz,得引入全部文件,所以我选择用python中的pythonforwindows来调用rpc函数,这样就需要在python中获取cs文件中rpc服务对应的uuid,版本号
https://hakril.github.io/PythonForWindows/build/html/rpc.html为pythonforwindows的官方文档,供使用参考。
获取uuid,版本并尝试连接
c#的整体结构还是相对好解析,非常规整,完全可以通过{ } ;和( ) ,分别解析类和函数,再删除不必要的# //行,可以大致将所有类,结构体,union,接口和接口中的参数进行分类,再返回一个列表,方便后面获取值。
根据对应类型生成参数
c#生成的idl文件中也将参数用ntapidotnet中的对应函数进行了包装,例如用WriteTerminatedString包装String,用WriteInt32包装int,WriteReferent将里面的类型转为UniquePTR,或是自定一个Write_xx处理一些数组、结构体或union之类的东西。通过c#中的函数得到参数对应的包装方式,再记录为pythonforwindows中对应的类型如NdrWString,NdrLong,NdrByte之类的,会比从函数参数中直接翻译更加准确
还有一些参数嵌套了好几层结构体,写个解析函数在碰到结构体的时候回调解析就行。最后返回一个列表包含了所有参数的类型。
值得注意的是pythonforwindows并没有将所有类型完全解析,不能将c#所有包装函数完全对应上pythonforwindows中的类型,比如union的包装方式就没有在pythonforwindows中提供(可以看ntapidotnet中的源码,union的包装方式是将int类型的selector用NdrLong包装,再拼接上selector对应的参数包装),但作为fuzz,其实我们也不需要对所有类型完全进行处理,遇到不能处理的类型直接用byte数组代替就好。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
解析idl生成的cs文件,使其变为可供python使用的函数集,含有uuid,版本,结构体和结构体内参数,方法和参数
用ntapidotnet遍历出可供c#调用的idl文件
https://github.com/tyranid/WindowsRpcClients中有对应的导出方法,或直接引用他提供的
但是在c#中调用函数需要using引入,这样就没法遍历所有文件自动fuzz,得引入全部文件,所以我选择用python中的pythonforwindows来调用rpc函数,这样就需要在python中获取cs文件中rpc服务对应的uuid,版本号
https://hakril.github.io/PythonForWindows/build/html/rpc.html为pythonforwindows的官方文档,供使用参考。
获取uuid,版本并尝试连接
c#的整体结构还是相对好解析,非常规整,完全可以通过{ } ;和( ) ,分别解析类和函数,再删除不必要的# //行,可以大致将所有类,结构体,union,接口和接口中的参数进行分类,再返回一个列表,方便后面获取值。
根据对应类型生成参数
c#生成的idl文件中也将参数用ntapidotnet中的对应函数进行了包装,例如用WriteTerminatedString包装String,用WriteInt32包装int,WriteReferent将里面的类型转为UniquePTR,或是自定一个Write_xx处理一些数组、结构体或union之类的东西。通过c#中的函数得到参数对应的包装方式,再记录为pythonforwindows中对应的类型如NdrWString,NdrLong,NdrByte之类的,会比从函数参数中直接翻译更加准确
还有一些参数嵌套了好几层结构体,写个解析函数在碰到结构体的时候回调解析就行。最后返回一个列表包含了所有参数的类型。
值得注意的是pythonforwindows并没有将所有类型完全解析,不能将c#所有包装函数完全对应上pythonforwindows中的类型,比如union的包装方式就没有在pythonforwindows中提供(可以看ntapidotnet中的源码,union的包装方式是将int类型的selector用NdrLong包装,再拼接上selector对应的参数包装),但作为fuzz,其实我们也不需要对所有类型完全进行处理,遇到不能处理的类型直接用byte数组代替就好。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke