python shellcode,shellcoder编程揭秘
每甜美的裙子听到外壳代码(外壳代码)一定会想到病毒与安全。其实外壳代码(外壳代码)并没有你想想中的那么难,它有一个特点就是把它嵌入到任何进程中都能够运行。是不是感觉很牛逼。但是我们分析一下什么代码能够不依赖任何环境呢?首先这段代码不能够有常量区~我爱你~静态区数据。也就是说不能够有全局变量。还有不能有类似char str[]={hello word}:这样的数据,因为这样的数据在常量区。同时不能够有系统调用和函数调用。甜美的裙子代码包含以上这些条件。那么恭喜你已经完成了一个雪莱代码。下面我们就简单分析一个窗子操作系统下弹邮箱(五)这段代码如何书写。
首先需要获取到内核32。动态链接库的基地址。我们可以用以下两种方法,其原理都是一样的,我希望你和我一样想知道为什么这么写,那么我们来探究为什么这样写。
S7-1200可编程控制器:获取皮巴基址MOVEAX,DWORD PTR DS : [EAX0xC]/:获取S7-1200可编程控制器结构指针MOV ESI,DWORD PTR DS : [EAX0x1C]/:获取ininitializationordermodulelist启动模组清单成员指针LODS德沃德PTR DS : [ESI]/:把ESI(ESI)地址里的值给EAX(阿拉伯国家联盟),同时ESI(ESI)自己加四个,相当于获取下一个节点MOVEBX、德沃德PTR DS : [EAX 8]/:取其基地址,该结构当前包含的是内核32 .dllmov dwkernelbase,ebx)_ ASM { mov eax,DWORD PTR FS:[0x30]//0x030进程块环境:Ptr32 _PEB*mov eax,dword ptr ds:[eax0x 0c]//0x 00 c ldr:ptr 32 _ peb _ ldr _ data * mov eax,dword ptr ds:[eax0x 1c]//0x 01 c in initializationorder modulelist:_ list _ entry ymov pbeg,EAG自己定义的pvoidmov eax,[eax]//地址里的值指向下一个mov pPLD、eax //pPLD函数自己定义的pvoid遍历找到内核32.dlldo{PVOID基本地址=(PV oid)*(((PD word)((dword)ppld0x 08));PV oid full dll name=(PV oid)*(PD word)((dword)ppld0x 20));wchar * SZ name=(wchar *)完整的dllnamePlast=(word *)full dllname;pfilst=(word *)SZ内核32;而(* pf rst * pf rst=* Plast){ pf rst;石膏;石膏;}如果(* pf rst==* Plast){ dwcore base=(dword)基址;打断;打断;} ppld=(PV oid)*((PD word)ppld);}而(pPLD!=pbeg要想理解上面的代码就要知道文件系统:[0]相当于基地址为当前线程的线程环境块(TEB),所以该段也被称为泰布段。下面就是泰布的结构体
/*
cefclient!_TEB
0x000 NtTib : _NT_TIB
0x01c环境指针:Ptr32端口
0x020客户端Id:_客户端ID
0x 028有效rpchande:ptr 32端口
0x02c线程局部存储指针:Ptr32无效
0x030工艺环境块:Ptr32 _PEB//进程环境块皮巴
0x034负载保留数:Uint4B
0x 038 countofownecritical函数:Uint4B
0x 03 c csrclietthread:ptr 32 void
0x 040 win32线程信息:Ptr32无效
*/
我们看到了皮巴在偏移0x30(零乘以30)的位置所以你很好理解mov eax dword ptr fs:[0x 30]这句汇编了吧。
/*
cefclient!_PEB
0x000继承计量空间:UChar
0x001 ReadImageFileExecOptions:侦听
0x002腿部沸腾:倾听
0x003位场:UChar
0x 003图像使用标签页:位置0.1位
0x 003受保护的进程:位置1.1位
0x 003图像动态定位:位置2.1位
0x 003 skippatchinguser 32个转发程序:位置3.1位
0x 003 isppackagedpprocess:位置4.1位
0x 003 isappcontainer:位置5.1位
0x 003受保护的过程灯:位置6.1位
0x003存贮器位:位置7.1位
0x004突变体:Ptr32无效
0x 008 imagebase address:ptr 32 void
0x00c Ldr:ptr 32 _ PEB _ LDR _数据//进程加载的模块链表ldr!连接酶检测反应
0x010工艺参数:ptr 32 _ RTL _用户_流程_参数
0x014子系统数据:Ptr32无效
0x018进程堆:Ptr32无效
0x 01 c快速peblock:ptr 32 _ RTL _关键_部分-快速编码块
0x 020 atlthunkslistptr:ptr 32 void
0x 024 ifokey:ptr 32 void
0x028交叉进程标志:Uint4B*/
这下我们理解了mov eax dword ptr ds:[eax0x 0c]//0x 00 c ldr:ptr 32 _ peb _ ldr _ data *
/*
cefclient!S7-1200可编程控制器
0x000长度:Uint4B
0x004初始化:UChar
0x 008s handle:ptr 32 Void
0x00c InLoadOrderModuleList:_ LIST _ ENTRY
0x 014 InMemoryOrderModuleList:_ LIST _ ENTRY
01C初始化OrderModulelist:_ list _ entry//获取初始化序列模块链表。
0x024条目进度:Ptr32无效
0x 028 shutdowinprogress:UChar
0x02c关闭线程Id : Ptr32 Void
*/对应的mov eax,dword ptrds:[eax0x1c]//0x01c n初始化ordermodulelist: _ list _ entry
让我们来看看。
pbeg,eax//先用PBEG保存第一个链表的地址。
Mov eax,[eax]//地址中的值指向下一个
Mov pPLD,eax//pPLD保存下一个指向的地址。
这是我在网上找到的一张图片。感觉很生动,理解上面的结构。
但是我们在第三个列表中选择了下一个节点。所以这个图有些问题,但是原理是一样的。你知道我们是怎么找到KERNEL32.DLL的基本地址的吗?我推荐用第二种方法来找基址。一中只针对win7以上的系统。第二种方法通过比较字符串来确定基址更准确。
我们找到了KERNEL32.DLL的基本地址。现在,如何找到GetProcAddress函数的地址。这就需要你对PE文件有所了解。知道导出表在哪里。代码如下所示
IMAGE _ DOS _ HEADER * pIDH=(IMAGE _ DOS _ HEADER *)dwKernelBase;//获取基址DOS头image _ nt _ headers * pings=(image _ nt _ headers *)((dword)dwkernelbase pidh-e _ lf anew);//找到NT头image _ export _ directory * pie=(image _ export _ directory *)((dword)dwkernelbasepings-可选header.datadirectory [0]。virtual address);//找到导出表位置dword * paddofun _ raw=(dword *)((dword)dwkernelbase pied-address of functions);//导出表对应的地址有三个,我就不说它们之间的关系了。自己查看导出表word * paddoford _ raw=(word *)((dword)dwkernelbase Pied-AddressofNameaddresses);DWORD * pAddOfofNames _ Raw=(DWORD *)((DWORD)dwKernelBase pIED-AddressOfNames);接下来,我们需要获取特定GetProcAddress函数的地址。
//PE(导出表)-为(;dwCntpIED-number of names;dw CNT){ pFinded=(char *)((DWORD)dwKernelBase pAddOfofNames _ Raw[dw CNT]);//名称表对应多名称地址while(* pFinded * pFinded==* PSRC)//比较GetProcAddress字符串{ pFindedpSrc} if(* p found==* PSRC)//比较成功{ pgetaddress=(pgetaddress)((dword)dwkernelbase paddofun _ raw[paddoford _ raw[dw CNT]]);//名称表对应的序号表的地址中的内容是对应的多功能地址断;} pSrc=szGetProcAddr}于是我们找到了GetProcAddress函数地址,用它我们可以得到任何想要加载的函数。
//获取其他函数地址pload library=(pload library)pgetaddress((hmodule)dwkernelbase,szloadlibrary);pMessageBox=(pMessageBox)pGetProcAddress((HMODULE)pLoadLibrary((LPCTSTR)SZ user 32),SZ messagebox);char strtest[]={ S , h , e , l , C , o , d , e ,0 };char strContent[]={ l , I , u , g , x ,0 };pMessageBox(NULL,(LPCTSTR)strtest,(LPCTSTR)strContent,0);于是我们成功调用了MessageBox函数。甜裙把上面的代码变成硬代码,然后可以嵌入到其他进程中运行。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。